AJAX跨域调用

发布于 2024-08-27 04:37:05 字数 254 浏览 4 评论 0 原文

我了解AJAX跨域策略。 所以我不能只通过 ajax HTTP 请求调用“http://www.google.com”并显示 结果在我的网站上的某个地方。

我尝试使用 dataType“jsonp”,这实际上可以工作,但我收到语法错误(显然是因为接收到的数据不是 JSON 格式)

是否有其他可能性从外部域接收/显示数据? iFrame 遵循相同的政策吗?

I know about AJAX cross-domain policy.
So I can't just call "http://www.google.com" over a ajax HTTP request and display
the results somewhere on my site.

I tried it with dataType "jsonp", that actually would work, but I get a syntax error (obviously because the received data is not JSON formated)

Is there any other possiblity to receive/display data from a foreign domain?
iFrames follow the same policy?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

合久必婚 2024-09-03 04:37:05

使用 AJAX 获取跨域数据的唯一(简单)方法是使用服务器端语言作为代理,如 安迪 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']);

就这么简单。只需注意您可以或不可以对抓取的数据做什么。

The only (easy) way to get cross-domain data using AJAX is to use a server side language as the proxy as Andy E noted. Here's a small sample how to implement that using jQuery:

The jQuery part:

$.ajax({
    url: 'proxy.php',
    type: 'POST',
    data: {
        address: 'http://www.google.com'
    },
    success: function(response) {
        // response now contains full HTML of google.com
    }
});

And the PHP (proxy.php):

echo file_get_contents($_POST['address']);

Simple as that. Just be aware of what you can or cannot do with the scraped data.

执笔绘流年 2024-09-03 04:37:05

您需要将脚本标记动态插入到引用数据的页面中。使用 JSONP,您可以在脚本加载后执行一些回调函数。

JSONP 上的维基百科页面有一个简洁的示例;脚本标记:

<script type="text/javascript" src="http://domain1.com/getjson?jsonp=parseResponse">
</script>

将返回包含在对 parseResponse 的调用中的 JSON 数据:(

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);

You will need to dynamically insert a script tag into the page that references the data. Using JSONP, you can execute some callback function when the script has loaded.

The wikipedia page on JSONP has a concise example; the script tag:

<script type="text/javascript" src="http://domain1.com/getjson?jsonp=parseResponse">
</script>

would return the JSON data wrapped in a call to parseResponse:

parseResponse({"Name": "Cheeso", "Rank": 7})

(depending on the configuration of the getjson script on domain1.com)

The code to insert the tag dynamically would be something like:

var s = document.createElement("script");
s.src = "http://domain1.com/getjson?jsonp=parseResponse";
s.type = "text/javascript";
document.appendChild(s);
ぶ宁プ宁ぶ 2024-09-03 04:37:05

您可以使用 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 */}
);

You can use YQL to do the request without needing to host your own proxy. I have made a simple function to make it easier to run commands:

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);
}

If you have jQuery, you may use $.getJSON instead.

A sample may be this:

RunYQL('select * from html where url="http://www.google.com/"',
       function(data){/* actions */}
);
只为守护你 2024-09-03 04:37:05

不幸的是(或者幸运的是)没有。跨域策略的存在是有原因的,如果很容易绕过它,那么它作为一种安全措施就不会非常有效。除了 JSONP 之外,唯一的选择是使用您自己的服务器代理页面

对于 iframe,它们遵循相同的策略。当然,您可以显示来自外部域的数据,只是无法操作它。

Unfortunately (or fortunately) not. The cross-domain policy is there for a reason, if it were easy to get around it then it wouldn't be very effective as a security measure. Other than JSONP, the only option is to proxy the pages using your own server.

With an iframe, they are subject to the same policy. Of course you can display the data from an external domain, you just can't manipulate it.

厌味 2024-09-03 04:37:05

我使用这段代码进行跨域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 约束的影响。

我们将讨论在步骤 调用此 AJAJ ~ 异步 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 格式,不要忘记。

我希望这对您有所帮助,感谢您的耐心:-),请放心,对代码格式表示抱歉,它不能很好地工作

I use this code for cross domain ajax call, I hope it will help more than one here. I'm using Prototype library and you can do the same with JQuery or Dojo or anything else:

Step 1: create a new js file and put this class inside, I called it 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) ;
    }

}) ;

This class creates a dynamic script element which src attributes targets your JSON data provider (JSON-P in fact as your distant server must provide the data in this format :: call_back_function(//json_data_here) :: so when the script tag is created your JSON will be directly evaled as a function (we'll talk about passing the callback method name to server on step 2), the main concept behind this is that script like img elements are not concerned by the SOP constraints.

Step2: in any html page where you wanna pull the JSON asynchronously (we call this AJAJ ~ Asynchronous JAvascript + JSON :-) instead of AJAX which use the XHTTPRequest object) do like below

//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 
        }) ;

D'you remenber the callback on step 1? so we pass it to the server and it will returns the JSON embeded in that method so in our case the server will return an evalable javascript code xss_crawler.process(//the_json_data), remember that xss_crawler is an instance of WSAjax class. The server code depends on you (if it's yours), but most of Ajax data providers let you specify the callback method in parameters like we did.
In Ruby on rails I just did

render :json=>MyModel.all(:limit=>10), :callback => params[:callback],:content_type => "application/json"

and that's all, you can now pull data from another domain from your apps (widgets, maps etc), in JSON format only, don't forget.

I hope it was helpfull, thanks for your patience :-), peace and sorry for code formatting, it doesn't work well

陈甜 2024-09-03 04:37:05

如果您使用 php 脚本从远程服务器获取答案,请在开头添加以下行:

header("Access-Control-Allow-Origin: *");

If you are using a php script to get the answer from the remote server, add this line at the begining:

header("Access-Control-Allow-Origin: *");
旧人 2024-09-03 04:37:05

经过一些研究后,此问题的唯一“解决方案”是调用:

if($.browser.mozilla)
   netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');

这将询问用户是否允许网站继续。他确认后,所有
无论数据类型如何,ajax 调用都会被执行。

这适用于 mozilla 浏览器,在 IE < 8、用户必须允许跨域调用
以类似的方式,某些版本需要在浏览器选项中进行配置。

chrome/safari:到目前为止我还没有找到这些浏览器的配置标志。

使用 JSONP 作为数据类型会很好,但就我而言,我不知道我是否需要域
访问支持该格式的数据。

另一种方法是使用 HTML5 postMessage,它也可以跨域,但我不能
我的用户注定会选择 HTML5 浏览器。

after doing some research, the only "solution" to this problem is to call:

if($.browser.mozilla)
   netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');

this will ask an user if he allows a website to continue. After he confirmed that, all
ajax calls regardless of it's datatype will get executed.

This works for mozilla browsers, in IE < 8, an user has to allow a cross domain call
in a similar way, some version need to get configured within browser options.

chrome/safari: I didn't find a config flag for those browsers so far.

using JSONP as datatype would be nice, but in my case I don't know if a domain I need
to access supports data in that format.

Another shot is to use HTML5 postMessage which works cross-domain aswell, but I can't
afford to doom my users to HTML5 browsers.

瑶笙 2024-09-03 04:37:05

在我看来,JSONP 是最好的选择。尝试找出为什么会出现语法错误 - 您确定收到的数据不是 JSON 吗?那么也许你以某种方式错误地使用了 API。

您可以使用的另一种方法(但我认为它不适用于您的情况)是在页面中放置一个 iFrame,其中 src 位于您要调用的域中。让它为您执行调用,然后使用 JS 在 iF​​rame 和页面之间进行通信。这将绕过跨域,但前提是您可以在要调用的域中拥有 iFrame 的 src 。

JSONP is the best option, in my opinion. Try to figure out why you get the syntax error - are you sure the received data is not JSON? Then maybe you're using the API wrong somehow.

Another way you could use, but I don't think that it applies in your case, is have an iFrame in the page which src is in the domain you want to call. Have it do the calls for you, and then use JS to communicate between the iFrame and the page. This will bypass the cross domain, but only if you can have the iFrame's src in the domain you want to call.

夜声 2024-09-03 04:37:05

这是一种简单的方法,无需使用任何花哨的东西,甚至不需要使用 JSON。

首先,创建一个服务器端脚本来处理您的请求。类似于 http://www.example.com/path/handler.php

你会使用参数调用它,如下所示: .../handler.php?param1=12345¶m2=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);

此方法的唯一限制是可以发送到服务器的参数的最大长度。但是,您始终可以发送多个请求。

Here is an easy way of how you can do it, without having to use anything fancy, or even JSON.

First, create a server side script to handle your requests. Something like http://www.example.com/path/handler.php

You will call it with parameters, like this: .../handler.php?param1=12345¶m2=67890

Inside it, after processing the recieved data, output:

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

Now, in the client side script, use the following:

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);

The only limit of this approach, is the max length of parameters that you can send to the server. But, you can always send multiple requests.

明月夜 2024-09-03 04:37:05

您可以使用 CORS 技术来配置两台服务器(运行 Javascript 的服务器和外部 API 服务器)

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

ps:答案https://stackoverflow.com/a/37384641/6505594也建议采用这种方法,并且它向其他人开放外部API服务器来调用它。

You can use the technology CORS to configure both servers (the server where the Javascript is running and the external API server)

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

p.s.: the answer https://stackoverflow.com/a/37384641/6505594 is also suggesting this approach, and it's opening the external API server to everyone else to call it.

绝影如岚 2024-09-03 04:37:05

我在两天内遇到了同样的问题,我找到了解决方案,经过大量谷歌搜索后它很优雅。
我需要 xss Ajax 来处理一些小部件客户端,这些客户端将数据流从 Tiers 网站提取到我的 Rails 应用程序。
这是我的做法。

I faced the same problem during 2 days and I found the solution, and it's elegant after googling a lot.
I needed xss Ajax for some widget clients which pull datastream from tiers websites to my Rails app.
here's how I did.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文