23

如何使用用户浏览器中的 JavaScript 向其他服务器发出请求(即从任何所需的服务器获取页面)?对于像 XMLHttpRequest 这样的方法,有一些限制可以防止这种情况发生,有没有办法绕过它们或其他方法?

这是一个普遍的问题,具体我想检查一系列随机网站,看看它们是否包含某个元素,所以我需要一个网站的 HTML 内容,而不需要下载任何额外的文件;所有这些都在一个 JavaScript 文件中,在服务器上没有任何转发或代理机制

(注意:一种方法是使用 Greasemonkey 及其 GM_xmlhttpRequest。)

4

8 回答 8

23

你应该看看jQuery。它具有丰富的AJAX 功能基础,可以让您完成所有这些工作。您可以加载外部页面,并使用直观的类似 CSS 的选择器解析其 HTML 内容。

使用示例$.get();

$.get("anotherPage.html", {}, function(results){
  alert(results); // will show the HTML from anotherPage.html
  alert($(results).find("div.scores").html()); // show "scores" div in results
});

对于外部域,我不得不编写一个充当中间人的本地 PHP 脚本。jQuery 将调用本地 PHP 脚本,传入另一个服务器的 URL 作为参数,本地 PHP 脚本将收集数据,jQuery 将从本地 PHP 脚本中读取数据。

$.get("middleman.php", {"site":"http://www.google.com"}, function(results){
  alert(results); // middleman gives Google's HTML to jQuery
});

middleman.php一些类似的东西

<?php

  // Do not use as-is, this is only an example.
  // $_GET["site"] set by jQuery as "http://www.google.com"
  print file_get_contents($_GET["site"]);

?>
于 2009-02-23T15:50:01.120 回答
5

2018 年更新:

只有满足以下4个条件才能跨域访问

  • 在响应头有Access-Control-Allow-Origin: *

演示

$.ajax({
  url: 'https://api.myjson.com/bins/bq6eu',
  success: function(response){
    console.log(response.string);
  },
  error: function(response){
    console.log('server error');
  }
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

  • 使用服务器作为目标的桥接器或代理

演示:

$.ajax({
  url: 'https://cors-anywhere.herokuapp.com/http://whatismyip.akamai.com/',
  success: function(response){
    console.log('server IP: ' + response);
  },
  error: function(response){
    console.log('bridge server error');
  }
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

  • 使用浏览器插件启用Allow-Control-Allow-Origin: *
  • 禁用浏览器网络安全

铬合金

chrome.exe --args --disable-web-security

火狐

about:config -> security.fileuri.strict_origin_policy -> false

结尾


菜鸟旧答案 2011

$.get(); 可以从jsbin.com获取数据,但我不知道为什么它不能从 google.com 等其他网站获取数据

$.get('http://jsbin.com/ufotu5', {},
  function(results){  alert(results); 
});

演示: http: //jsfiddle.net/Xj234/ 使用 firefox、chrome 和 safari 进行测试。

于 2011-05-29T21:48:50.320 回答
3

编写一个代理脚本,沿着来自您的域的 http 请求转发,这将绕过 XMLHttpRequest 限制。

如果您使用 PHP,只需使用 cURL 请求并读取页面,然后只需将 html 吐出,就好像它来自您的域一样。

于 2009-02-23T15:51:38.417 回答
3

这相当容易......如果你知道几乎没有人分享的“秘密”技巧......

它叫雅虎QQ...

因此,为了重新获得“用户的权力”(并回到方便的口头禅:“从不接受不”),只需使用http://query.yahooapis.com/(而不是 php?代理服务器端脚本)。
jQuery 不是严格需要的。

示例 1:
使用类似 SQL 的命令:

select * from html 
where url="http://stackoverflow.com" 
and xpath='//div/h3/a'

以下链接将抓取 SO 以获取最新问题(绕过跨域安全公牛$#!7): http://query.yahooapis.com/v1/public/yql?q=select%20title%20from%20html%
20where %20url%3D%22http%3A%2F%2Fstackoverflow.com%22%20and%0A%20%20%20%20%20%20xpath%3D%27%2F%2Fdiv%2Fh3%2Fa%27%0A%20 %20%20%20&format=json&callback=cbfunc

如您所见,这将返回一个 JSON 数组(也可以选择 xml)并调用回调函数:cbfunc

事实上,作为“奖励”,每次您不需要从“标签汤”中正则表达式数据时, 您还可以保存一只小猫。

你听到你内心的疯狂小科学家开始咯咯地笑了吗?

然后查看此答案以获取更多信息(不要忘记更多示例的评论)。

祝你好运!

于 2013-03-08T07:02:06.163 回答
1

您还可以使用 iframe 来模拟 ajax 请求。这为您节省了为前端问题编写后端解决方案的麻烦。这是一个例子:

function setUploadEvent(typeComponet){
       var eventType = "";
       var iframe = document.getElementById("iframeId");
       try{
           /* for Mozilla / Opera9 */
           if (/(?!.*?compatible|.*?webkit)^mozilla|opera/i.test(navigator.userAgent)) {
                eventType = "onload";
           }else{
           /* IE  */
                eventType = "onreadystatechange";
           }

           iframe[eventType] = function(){
                var doc = iframe.contentDocument || iframe.contentWindow.document;
                var response = doc.body.innerHTML; /* or what ever content you are looking for */
             }
           }
       catch(e){
           alert("Error loading content")}
       } 

这应该够了吧。请注意,浏览器检测线不是最干净的,您绝对应该使用所有最常见的 JS 框架(Prototype、JQuery 等)中提供的检测线

于 2009-02-23T17:34:50.667 回答
0

您需要在服务器上编写一个代理来执行此操作。所有请求都将发送到您的服务器,然后您的服务器将加载 html 并将其发送回客户端。并且没有好的方法可以仅通过 javascript 来实现。
jQuery 包含使用 XmlHttpRequest 加载 JSON 数据或外部脚本的功能,但此功能不能用于 html 页面。你也可以查看这个 jQuery 邮件列表线程

于 2009-02-23T15:51:10.400 回答
0

<script language="JavaScript" type="text/javascript" src="http://www.example.com/hello.js"></script>

您可以将数据以数组、JSON 或类似的形式添加到 hello.js 中。示例: var daysInMonth = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);

从另一台服务器获取 JavaScript 并不简单.. :-)

于 2010-01-20T17:11:28.750 回答
0

非常感谢,这真是一个好技巧。我是这样做的:

测试.html

<!DOCTYPE html>
<html>
<head>
<script>
function loadXMLDoc()
{
if (window.XMLHttpRequest)
  {// code for IE7+, Firefox, Chrome, Opera, Safari
  xmlhttp=new XMLHttpRequest();
  }
else
  {// code for IE6, IE5
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
xmlhttp.onreadystatechange=function()
  {
  if (xmlhttp.readyState==4 && xmlhttp.status==200)
    {
    document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
    }
  }
xmlhttp.open("GET","sp.php",true);
xmlhttp.send();
}
</script>
</head>
<body>

<h2>Using the XMLHttpRequest object</h2>
<div id="myDiv"></div>
<button type="button" onclick="loadXMLDoc()">Change Content</button>

</body>
</html>

sp.php

<?php
  print file_get_contents("http://your.url.com/you-can-use-cross-domain");
?>
于 2013-08-08T05:16:27.000 回答