AJAX跨域调用
我知道AJAX跨域策略。 所以我不能只通过ajax HTTP请求调用“ http://www.google.com ”,并在我的网站某处显示结果。
我试着用dataType“jsonp”,实际上会工作,但我得到一个语法错误(显然,因为收到的数据不是JSON格式)
有没有其他的可能性来接收/显示来自外域的数据? iFrames遵循相同的政策?
使用AJAX获取跨域数据的唯一(简单)方法是使用服务器端语言作为Andy E指出的代理。 这里有一个小示例如何使用jQuery实现:
jQuery部分:
$.ajax({ url: 'proxy.php', type: 'POST', data: { address: 'http://www.google.com' }, success: function(response) { // response now contains full HTML of google.com } });
和PHP(proxy.php):
echo file_get_contents($_POST['address']);
就那么简单。 只要知道你可以或不可以用刮取的数据做什么。
您需要dynamic地将脚本标记插入到引用数据的页面中。 使用JSONP,您可以在加载脚本时执行一些callback函数。
JSONP上的wikipedia页面有一个简洁的例子。 脚本标签:
<script type="text/javascript" src="http://domain1.com/getjson?jsonp=parseResponse"> </script>
会将包含在调用中的JSON数据返回给parseResponse
:
parseResponse({"Name": "Cheeso", "Rank": 7})
(取决于domain1.com上的getjson
脚本的configuration)
dynamic插入标签的代码如下所示:
var s = document.createElement("script"); s.src = "http://domain1.com/getjson?jsonp=parseResponse"; s.type = "text/javascript"; document.appendChild(s);
您可以使用YQL来执行请求,而无需托pipe自己的代理。 我已经做了一个简单的函数来使命令更容易运行:
function RunYQL(command, callback){ callback_name = "__YQL_callback_"+(new Date()).getTime(); window[callback_name] = callback; a = document.createElement('script'); a.src = "http://query.yahooapis.com/v1/public/yql?q=" +escape(command)+"&format=json&callback="+callback_name; a.type = "text/javascript"; document.getElementsByTagName("head")[0].appendChild(a); }
如果你有jQuery,你可以使用$ .getJSON。
样本可能是这样的:
RunYQL('select * from html where url="http://www.google.com/"', function(data){/* actions */} );
不幸的是(或幸运的是)没有。 跨域政策是有原因的,如果它很容易绕过它,那么作为一个安全措施就不会很有效。 除了JSONP,唯一的select是使用您自己的服务器代理页面 。
使用iframe时,他们受制于相同的政策。 当然,你可以显示来自外部的数据,你不能操纵它。
我使用这个代码跨域Ajax调用,我希望这将有助于不止一个在这里。 我正在使用Prototype库,您可以使用JQuery或Dojo或其他任何东西:
第1步:创build一个新的js文件并把这个类放到里面,我把它叫做xss_ajax.js
var WSAjax = Class.create ({ initialize: function (_url, _callback){ this.url = _url ; this.callback = _callback ; this.connect () ; }, connect: function (){ var script_id = null; var script = document.createElement('script'); script.setAttribute('type', 'text/javascript'); script.setAttribute('src', this.url); script.setAttribute('id', 'xss_ajax_script'); script_id = document.getElementById('xss_ajax_script'); if(script_id){ document.getElementsByTagName('head')[0].removeChild(script_id); } // Insert <script> into DOM document.getElementsByTagName('head')[0].appendChild(script); }, process: function (data){ this.callback(data) ; } }) ;
这个类创build一个dynamic的脚本元素,其src属性的目标是你的JSON数据提供者(实际上,因为你的远程服务器必须以这种格式提供数据:: call_back_function(// json_data_here)::所以当脚本标签被创buildJSON将作为一个函数被直接撤销(我们将在步骤2中讨论将callback方法名称传递给服务器),其背后的主要概念是像img元素这样的脚本不受SOP约束的影响。
第二步:在任何想要asynchronous拉动JSON的html页面(我们称之为AJAJ〜Asynchronous JAvascript + JSON :-)而不是使用XHTTPRequest对象的AJAX)
//load Prototype first //load the file you've created in step1 var xss_crawler = new WSAjax ( "http://your_json_data_provider_url?callback=xss_crawler.process" , function (_data){ // your json data is _data and do whatever you like with it }) ;
你重新在第1步callback? 所以我们把它传递给服务器,它将返回embedded在该方法中的JSON,所以在我们的例子中,服务器将返回一个可消除的JavaScript代码xss_crawler.process(// the_json_data),请记住,xss_crawler是WSAjax类的一个实例。 服务器代码取决于你(如果是你的),但是大多数Ajax数据提供者可以让你像参数那样在参数中指定callback方法。 在Ruby上,我只是做了
render :json=>MyModel.all(:limit=>10), :callback => params[:callback],:content_type => "application/json"
就这样,你现在可以从你的应用程序(小部件,地图等)从另一个领域的数据,只有JSON格式,不要忘记。
我希望这是有用的,感谢您的耐心:-),和平和抱歉的代码格式,它不工作
在做了一些研究之后,解决这个问题的唯一办法是打电话给:
if($.browser.mozilla) netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');
这将询问用户是否允许网站继续。 在确认之后,所有的ajax调用都将被执行,而不pipe它的数据types如何。
这适用于Mozilla浏览器,在IE <8中,用户必须以类似的方式允许跨域调用,某些版本需要在浏览器选项中进行configuration。
铬/ safari:到目前为止,我没有find这些浏览器的configuration标志。
使用JSONP作为数据types会很好,但在我的情况下,我不知道我需要访问的域是否支持该格式的数据。
另一种方法是使用HTML5 postMessage,它可以跨域使用,但是我不能让用户使用HTML5浏览器。
在我看来,JSONP是最好的select。 试着弄清楚为什么你会得到语法错误 – 你确定收到的数据不是JSON吗? 那么也许你错误地使用了API。
另一种方式,你可以使用,但我不认为它适用于你的情况,有一个iFrame在页面中的src是你想要调用的域名。 让它为你打电话,然后使用JS在iFrame和页面之间进行通信。 这将绕过跨域,但只有当你想要调用的域中的iFrame的src。
这里是一个简单的方法,你可以做到这一点,而不必使用任何幻想,甚至JSON。
首先,创build一个服务器端脚本来处理您的请求。 就像http://www.example.com/path/handler.php
你会用参数调用它,像这样:… / handler.php?param1 = 12345&param2 = 67890
在里面,处理接收到的数据后, 输出 :
document.serverResponse('..all the data, in any format that suits you..'); // Any code could be used instead, because you dont have to encode this data // All your output will simply be executed as normal javascript
现在,在客户端脚本中,使用以下内容:
document.serverResponse = function(param){ console.log(param) } var script = document.createElement('script'); script.src='http://www.example.com/path/handler.php?param1=12345¶m2=67890'; document.head.appendChild(script);
这种方法的唯一限制是可以发送给服务器的最大参数长度。 但是,你总是可以发送多个请求。
如果您正在使用php脚本从远程服务器获取答案,请在开头添加以下行:
header("Access-Control-Allow-Origin: *");
您可以使用CORS技术来configuration两个服务器(运行Javascript的服务器和外部API服务器)
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
ps:答案https://stackoverflow.com/a/37384641/6505594也提示这种方法,它打开外部API服务器给其他人打电话给它。;
我在两天内遇到了同样的问题,我find了解决scheme,search了很多东西之后,它的优雅。 我需要一些小部件客户端的xss Ajax,这些小部件客户端将数据stream从层网站拉到我的Rails应用程序。 这是我做的。