您可以使用浏览器扩展来抓取外部页面,然后将数据发送到您的站点,或者在页面中显示它,以便您的页面的 javascript 通过 DOM 访问它。
您可以在您的域上使用代理来获取外部页面并将其交给您的 javascript,其来源也在您的域上。
您可以为可访问的外部页面使用 API。
您可以询问、命令、更改外部页面的代码(如果您可以访问它)以使用 Access-Control-Allow-Origin=* 提供页面服务
我想这就是你能做的。
编辑: “看起来很奇怪”是直到你意识到用户和进程之间的预期区别. 用户不被认为是恶意的,但进程可能是恶意的。例如,如果进程可以访问外部页面,则可以从用户登录的 gmail 会话中获取数据,并将该数据传输到服务器。由于终端上的用户可能(但不总是!)登录到该会话的用户,因此不认为该用户是恶意的。但是,其来源是用户导航到的某个网站的脚本不应该能够以与该用户相同的权限进行操作。由于该脚本也是一个代理,并且可以执行操作,但它不是由用户创建或指导的。这是隔离原产地和同源政策的最强有力的原因。
例子
Bookmarklet 和 IFrame 的执行上下文
如果您通过一个小书签将 JS 注入到每个页面中,那么注入的代码将表现得好像它与页面的其余部分具有相同的来源,或者至少是该页面的“顶部框架” . 它将在与顶部框架相同的上下文中执行。如果页面中有嵌套的 iframe,那么如果您的小书签尝试注入其中,您将收到“不安全地尝试从页面 x 访问”错误。这是因为小书签的来源在首页,而且首页无论如何都不能访问不同域上的嵌套 iframe。
因此,如果您希望抓取的网站的某些部分位于顶部框架下方的 iframe 中,您的小书签将无法获取它。
使用小书签传输数据
如果您想在一个页面上获取一个 url,在您的域上,然后从该 url,在另一个域上获取数据,然后在同一页面上显示该数据,您需要一种方法来获取数据. 您可以使用书签,但流程仍将涉及一些“用户帮助”。它会是这样的:
- 加载您的域的页面,D. 用户将 url 放入输入框中。点击提交。
- D 上的 Javascript 打开一个指向用户提供的 url 的新选项卡/窗口。
- 用户在该外部页面上单击您的抓取书签,该页面收集所需的数据 X。
- 所需数据 X 通过 Ajax 发送到具有会话标识符 I 的“服务器”S。
- 页面 D,轮询服务器 S,直到它收到通知,一些具有会话标识符 I 的数据已被抓取,然后它获取该数据并将其显示在 D 上。
需要一台服务器。您不能使用本地存储来传输信息,因为这是特定于域的。有一个不需要服务器的替代方案。它需要制作浏览器扩展。
使用浏览器扩展传输数据 扩展的“背景页面”基本上与所有浏览器选项卡的本地服务器相同,它允许跨针对不同域的选项卡传输信息。此设置中的“客户端”是加载到每个页面的“内容脚本”(就像书签一样,除了不需要用户实际单击书签来加载它。它会自动发生)。流程是这样的:
- 又是 D 页。用户在输入框中输入 url。点击提交 -> 触发扩展中的一些代码。
- 扩展背景页面指示一个选项卡打开并将其定位到 url。
- 内容脚本会自动加载到该选项卡中,并在后台检查它应该获取的数据。它获取该数据,并通过消息(json 字符串)将其发送到后台页面。
- 后台页面将该通知和数据推送到页面 D 上的原始内容脚本。其中显示了信息。
- 可选地,后台页面还将信息传输到您的服务器以保存到该用户的数据存储中。
我用于浏览器扩展“背景页面”和“内容脚本”的语言主要集中在 Google Chrome 上。同样的概念在 Safari 和 Firefox 中也可用。如果您想支持 IE,您将不得不解决其他问题。IE10 甚至不打算支持扩展。