我了解AJAX跨域策略。 所以我不能只通过ajax HTTP请求和显示调用“http://www.google.com” 在我的网站上某处的结果。
我尝试使用dataType“jsonp”,实际上可以工作,但我得到一个语法错误(显然是因为收到的数据不是JSON格式化的)
是否还有其他可能从外国域接收/显示数据? iFrame遵循相同的政策?
答案 0 :(得分:65)
使用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']);
这很简单。请注意您使用已删除数据可以做什么或不做什么。
答案 1 :(得分:19)
您需要在引用数据的页面中动态插入脚本标记。使用JSONP,您可以在脚本加载时执行一些回调函数。
JSONP上的维基百科页面有一个简明的例子;脚本标签:
<script type="text/javascript" src="http://domain1.com/getjson?jsonp=parseResponse">
</script>
会返回调用parseResponse
:
parseResponse({"Name": "Cheeso", "Rank": 7})
(取决于domain1.com上getjson
脚本的配置)
动态插入标记的代码如下:
var s = document.createElement("script");
s.src = "http://domain1.com/getjson?jsonp=parseResponse";
s.type = "text/javascript";
document.appendChild(s);
答案 2 :(得分:16)
您可以使用YQL来执行请求,而无需托管您自己的代理。我做了一个简单的函数,以便更容易运行命令:
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 */}
);
答案 3 :(得分:11)
不幸的是(或幸运的是)没有。跨域策略是有原因的,如果它很容易解决它,那么它作为安全措施就不会非常有效。除了JSONP之外,唯一的选择是proxy the pages using your own server。
使用iframe,它们遵循相同的政策。当然,您可以显示来自外部域的数据,您无法操纵它。
答案 4 :(得分:4)
if($.browser.mozilla)
netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');
这将询问用户是否允许网站继续。在他确认之后,全部 ajax调用无论它的数据类型都会被执行。
这适用于Mozilla浏览器,在IE&lt;如图8所示,用户必须允许跨域调用 以类似的方式,某些版本需要在浏览器选项中进行配置。
chrome / safari:到目前为止,我没有为这些浏览器找到配置标志。
使用JSONP作为数据类型会很好,但在我的情况下我不知道我是否需要一个域 访问支持该格式的数据。
另一个镜头是使用HTML5 postMessage,它也适用于跨域,但我不能 让我的用户陷入HTML5浏览器。
答案 5 :(得分:4)
我使用此代码进行跨域ajax调用,我希望它在这里可以帮助多个。我正在使用Prototype库,你可以使用JQuery或Dojo或其他任何东西:
步骤1:创建一个新的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) ;
}
}) ;
这个类创建了一个动态脚本元素,其中src属性以JSON数据提供者为目标(实际上JSON-P因为你的远程服务器必须以这种格式提供数据:: call_back_function(// json_data_here)::所以当脚本标签创建你的JSON将直接作为一个函数被唤醒(我们将讨论在第2步将回调方法名称传递给服务器),其背后的主要概念是像img元素这样的脚本不关心SOP约束。
Step2:在你想要异步提取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步的回调吗?所以我们将它传递给服务器,它将返回嵌入在该方法中的JSON,因此在我们的例子中,服务器将返回一个可变的javascript代码xss_crawler.process(// the_json_data),请记住xss_crawler是WSAjax类的一个实例。服务器代码取决于您(如果它是您的),但大多数Ajax数据提供程序允许您像我们一样在参数中指定回调方法。
在Ruby on rails上我刚刚做了
render :json=>MyModel.all(:limit=>10), :callback => params[:callback],:content_type => "application/json"
就是这样,你现在可以从你的应用程序(小部件,地图等)中提取数据,只有JSON格式,不要忘记。
我希望它有所帮助,感谢您的耐心:-),和平并抱歉代码格式化,它不能正常工作
答案 6 :(得分:3)
如果您使用php脚本从远程服务器获取答案,请在开头添加此行:
header("Access-Control-Allow-Origin: *");
答案 7 :(得分:2)
您可以使用的另一种方式,但我不认为它适用于您的情况,在页面中有一个iFrame,其中src位于您要调用的域中。让它为你做调用,然后使用JS在iFrame和页面之间进行通信。这将绕过跨域,但前提是您可以在要调用的域中拥有iFrame的src。
答案 8 :(得分:1)
这是一种简单的方法,可以帮助您完成任务,而不必使用任何花哨的东西,甚至是JSON。
首先,创建一个服务器端脚本来处理您的请求。像http://www.example.com/path/handler.php
这样的东西您将使用参数调用它,例如:... / handler.php?param1 = 12345&amp; 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);
此方法的唯一限制是您可以发送到服务器的参数的最大长度。但是,您始终可以发送多个请求。
答案 9 :(得分:0)
您可以使用CORS技术配置两台服务器(运行Javascript的服务器和外部API服务器)
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
p.s:答案https://stackoverflow.com/a/37384641/6505594也建议采用这种方法,并且打开外部API服务器给其他人调用它。
答案 10 :(得分:-3)
我在2天内遇到了同样的问题,我找到了解决方案,并且在google搜索后很优雅。 我需要一些小部件客户端的xss Ajax,它将数据流从层网站拉到我的Rails应用程序。 here's how I did.