【问题标题】:Using cURL to retrieve website and bypass same origin restriction, inserting javascript使用 cURL 检索网站并绕过同源限制,插入 javascript
【发布时间】:2013-01-03 08:30:13
【问题描述】:

我需要在 iframe 中加载多个网站,同时还要在每个页面中添加一个谷歌翻译插件,以便可以翻译它们。这是我插入部分的代码:

<iframe onload="googleJS1(); googleJS2(); googleJS3();" class=iframe2 src=http://localhost:8888/mysitep></iframe>

<script>
    function googleJS1() {
        var iframe = document.getElementsByTagName('iframe')[0];
        var doc = iframe.contentWindow.document;
        var newScript = doc.createElement('div');
        newScript.setAttribute("id", "google_translate_element");
        var bodyClass = doc.getElementsByTagName('body')[0];
        bodyClass.insertBefore(newScript, bodyClass.childNodes[0]);
    }

    function googleJS2() {
        var iframe = document.getElementsByTagName('iframe')[0];
        var doc = iframe.contentWindow.document;
        var newScript = doc.createElement('script');
        newScript.setAttribute("src", "http://translate.google.com/translate_a/element.js?    cb=googleTranslateElementInit");
        var bodyClass = doc.getElementsByTagName('head')[0];
        bodyClass.insertBefore(newScript, bodyClass.childNodes[1]);
    }

    function googleJS3() {
        var iframe = document.getElementsByTagName('iframe')[0];
        var doc = iframe.contentWindow.document;
        var newScript = doc.createElement('script');
        newScript.setAttribute("src", "http://localhost:8888/mysite/google.js");
        var bodyClass = doc.getElementsByTagName('head')[0];
        bodyClass.insertBefore(newScript, bodyClass.childNodes[2]);
    }
}
</script>

只要 iframe 目标 URL 位于同一服务器上,此方法就可以工作。我阅读以绕过相同的来源约束,我应该设置代理服务器并通过代理传递所有 URL 请求。所以我阅读了 cURL 并尝试了这个作为测试:

<?php

function get_data($url) {
    $ch = curl_init();
    $timeout = 5;
    curl_setopt($ch,CURLOPT_USERAGENT, $userAgent);
        curl_setopt($ch,CURLOPT_URL,$url);
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
    curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,$timeout);
    curl_setopt($ch,CURLOPT_FOLLOWLOCATION,true);
    $data = curl_exec($ch);
    curl_close($ch);
    return $data;
}

$test = get_data("http://www.selfridges.com");
echo $test;

?>

加载了基本的 HTML 元素,但没有加载 CSS 和图像。此外,链接仍然指向原始 URL。我需要一些关于如何将 CSS、图像和 js 从目标 URL 拉到代理并从那里加载页面的建议,使其看起来像是来自相同的域和端口并通过相同的源策略。我还需要链接以这种方式工作。

例如:

main page - http://localhost:8888/proxy.php 

links     - http://localhost:8888/proxy.php/products/2012/shoes

也欢迎任何其他方法或替代方案。

谢谢

【问题讨论】:

  • 使用用户代理来模仿 GoogleBot 可能是个坏主意。
  • 那么你就不需要用户代理了——curl会自动发送一个。
  • 删除了,顺便说一句,你对我的问题有什么想法吗?

标签: php javascript curl cross-domain same-origin-policy


【解决方案1】:

假设您的目标文档中的所有链接和图像都是相对的,您可以将base 标记注入头部。这将有效地使链接成为绝对链接,因此链接和图像仍将引用目标域(而不是您的域)。

http://reference.sitepoint.com/html/base

但不确定这将如何处理 css 图像。

一个对任何目标站点都有效的解决方案将是困难 - 您不仅需要解析 html 中的链接,还需要解析任何 css 引用中的链接。一些网站可能会使用 AJAX 来填充页面,这也会导致目标网站出现同源策略问题。

【讨论】:

  • 我假设它类似于这个问题stackoverflow.com/questions/6326297/load-external-sites-content 中的解决方案,其中所有链接都必须被解析,以便它们在开始时是我的“localhost:8888/”。你会说使用 wget 下载整个站点然后在我的服务器上运行它会是一个解决方案吗? wget 可以下载动态 php 网站吗?
  • 是的,但网站不再是动态的
  • 让我们的网站使用 Wordpress 或其他一些 CMS,使用 wget 下载后,内容仍然可以以静态格式访问还是根本无法访问?
  • 当然它仍然可以访问 - wget 以与浏览器相同的方式获取页面,它只是不显示页面。
  • 如果页面不显示那就不好了,所以它对我的情况并不是很有用。参考您的回答,“这将有效地使链接成为绝对,因此链接和图像仍将引用目标域(而不是您的)。”这是否意味着点击这些链接会将用户带到目标域?这意味着在这些链接之后我仍然会遇到相同的来源问题?
猜你喜欢
  • 1970-01-01
  • 2021-06-29
  • 2014-03-17
  • 1970-01-01
  • 2023-03-03
  • 2021-07-09
  • 2016-04-27
  • 1970-01-01
  • 2015-09-14
相关资源
最近更新 更多