Javascript jQuery AJAX 跨域

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3506208/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 04:57:27  来源:igfitidea点击:

jQuery AJAX cross domain

javascriptjqueryajaxjsoncross-domain

提问by Firose Hussain

Here are two pages, test.php and testserver.php.

这里有两个页面,test.php 和 testserver.php。

test.php

测试文件

<script src="scripts/jq.js" type="text/javascript"></script>
<script>
    $(function() {
        $.ajax({url:"testserver.php",
            success:function() {
                alert("Success");
            },
            error:function() {
                alert("Error");
            },
            dataType:"json",
            type:"get"
        }
    )})
</script>

testserver.php

测试服务器.php

<?php
$arr = array("element1",
             "element2",
             array("element31","element32"));
$arr['name'] = "response";
echo json_encode($arr);
?>

Now my problem: when both of these files are on the same server (either localhost or web server), it works and alert("Success")is called; If it is on different servers, meaning testserver.php on web server and test.php on localhost, its not working, and alert("Error")is executing. Even if the URL inside ajax is changed to http://domain.com/path/to/file/testserver.php

现在我的问题是:当这两个文件都在同一台服务器(本地主机或 Web 服务器)上时,它可以工作并被alert("Success")调用;如果它在不同的服务器上,意味着 web 服务器上的 testserver.php 和本地主机上的 test.php,它不工作,并且alert("Error")正在执行。即使ajax里面的URL改成http://domain.com/path/to/file/testserver.php

采纳答案by BGerrissen

Use JSONP.

使用JSONP

jQuery:

jQuery:

$.ajax({
     url:"testserver.php",
     dataType: 'jsonp', // Notice! JSONP <-- P (lowercase)
     success:function(json){
         // do stuff with json (in this case an array)
         alert("Success");
     },
     error:function(){
         alert("Error");
     }      
});

PHP:

PHP:

<?php
$arr = array("element1","element2",array("element31","element32"));
$arr['name'] = "response";
echo $_GET['callback']."(".json_encode($arr).");";
?>

The echo might be wrong, it's been a while since I've used php. In any case you need to output callbackName('jsonString')notice the quotes. jQuery will pass it's own callback name, so you need to get that from the GET params.

回声可能是错误的,自从我使用 php 以来已经有一段时间了。在任何情况下,您都需要输出callbackName('jsonString')通知引号。jQuery 将传递它自己的回调名称,因此您需要从 GET 参数中获取该名称。

And as Stefan Kendall posted, $.getJSON()is a shorthand method, but then you need to append 'callback=?'to the url as GET parameter (yes, value is ?, jQuery replaces this with its own generated callback method).

正如 Stefan Kendall 发布的那样,$.getJSON()是一种速记方法,但随后您需要将'callback=?'其作为 GET 参数附加到 url(是的,值是 ?,jQuery 将其替换为自己生成的回调方法)。

回答by joshuarh

JSONP is a good option, but there is an easier way. You can simply set the Access-Control-Allow-Originheader on your server. Setting it to *will accept cross-domain AJAX requests from any domain. (https://developer.mozilla.org/en/http_access_control)

JSONP 是一个不错的选择,但还有一种更简单的方法。您可以简单地Access-Control-Allow-Origin在服务器上设置标头。将其设置为*将接受来自任何域的跨域 AJAX 请求。( https://developer.mozilla.org/en/http_access_control)

The method to do this will vary from language to language, of course. Here it is in Rails:

当然,执行此操作的方法因语言而异。这是在 Rails 中:

class HelloController < ApplicationController
  def say_hello
    headers['Access-Control-Allow-Origin'] = "*"
    render text: "hello!"
  end
end

In this example, the say_helloaction will accept AJAX requests from any domain and return a response of "hello!".

在此示例中,该say_hello操作将接受来自任何域的 AJAX 请求并返回“hello!”响应。

Here is an example of the headers it might return:

以下是它可能返回的标头示例:

HTTP/1.1 200 OK 
Access-Control-Allow-Origin: *
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Type: text/html; charset=utf-8
X-Ua-Compatible: IE=Edge
Etag: "c4ca4238a0b923820dcc509a6f75849b"
X-Runtime: 0.913606
Content-Length: 6
Server: WEBrick/1.3.1 (Ruby/1.9.2/2011-07-09)
Date: Thu, 01 Mar 2012 20:44:28 GMT
Connection: Keep-Alive

Easy as it is, it does have some browser limitations. See http://caniuse.com/#feat=cors.

虽然很简单,但它确实有一些浏览器限制。请参阅http://caniuse.com/#feat=cors

回答by Adorjan Princz

You can control this via HTTP header by adding Access-Control-Allow-Origin. Setting it to * will accept cross-domain AJAX requests from any domain.

您可以通过添加Access-Control-Allow-Origin通过 HTTP 标头进行控制。将其设置为 * 将接受来自任何域的跨域 AJAX 请求。

Using PHPit's really simple, just add the following line into the script that you want to have access outside from your domain:

使用PHP非常简单,只需将以下行添加到您希望从域外部访问的脚本中:

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

Don't forget to enable mod_headers module in httpd.conf.

不要忘记在 httpd.conf 中启用 mod_headers 模块。

回答by Sarfraz

You need to have a look at Same Origin Policy:

您需要查看同源政策

In computing, the same origin policy is an important security concept for a number of browser-side programming languages, such as JavaScript. The policy permits scripts running on pages originating from the same site to access each other's methods and properties with no specific restrictions, but prevents access to most methods and properties across pages on different sites.

在计算中,同源策略是许多浏览器端编程语言(例如 JavaScript)的重要安全概念。该策略允许在来自同一站点的页面上运行的脚本在没有特定限制的情况下访问彼此的方法和属性,但阻止跨不同站点的页面访问大多数方法和属性。

For you to be able to get data, it has to be:

为了能够获取数据,它必须是:

Same protocol and host

相同的协议和主机

You need to implement JSONPto workaround it.

您需要实现JSONP来解决它。

回答by Whome

I had to load webpage from local disk "file:///C:/test/htmlpage.html", call "http://localhost/getxml.php" url, and do this in IE8+ and Firefox12+ browsers, use jQuery v1.7.2 lib to minimize boilerplate code. After reading dozens of articles finally figured it out. Here is my summary.

我必须从本地磁盘“file:///C:/test/htmlpage.html”加载网页,调用“http://localhost/getxml.php” url,并在 IE8+ 和 Firefox12+ 浏览器中执行此操作,使用 jQuery v1 .7.2 lib 以最小化样板代码。看了几十篇文章终于想通了。这是我的总结。

  • server script (.php, .jsp, ...) must return http response header Access-Control-Allow-Origin: *
  • before using jQuery ajax set this flag in javascript: jQuery.support.cors = true;
  • you may set flag once or everytime before using jQuery ajax function
  • now I can read .xml document in IE and Firefox. Other browsers I did not test.
  • response document can be plain/text, xml, json or anything else
  • 服务器脚本 (.php, .jsp, ...) 必须返回 http 响应头 Access-Control-Allow-Origin: *
  • 在使用 jQuery ajax 之前在 javascript 中设置这个标志: jQuery.support.cors = true;
  • 您可以在使用 jQuery ajax 函数之前设置一次或每次标记
  • 现在我可以在 IE 和 Firefox 中读取 .xml 文档了。其他浏览器我没有测试。
  • 响应文档可以是纯文本、xml、json 或其他任何内容

Here is an example jQuery ajax call with some debug sysouts.

这是一个带有一些调试系统输出的示例 jQuery ajax 调用。

jQuery.support.cors = true;
$.ajax({
    url: "http://localhost/getxml.php",
    data: { "id":"doc1", "rows":"100" },
    type: "GET",
    timeout: 30000,
    dataType: "text", // "xml", "json"
    success: function(data) {
        // show text reply as-is (debug)
        alert(data);

        // show xml field values (debug)
        //alert( $(data).find("title").text() );

        // loop JSON array (debug)
        //var str="";
        //$.each(data.items, function(i,item) {
        //  str += item.title + "\n";
        //});
        //alert(str);
    },
    error: function(jqXHR, textStatus, ex) {
        alert(textStatus + "," + ex + "," + jqXHR.responseText);
    }
});

回答by Jason

It is true that the same-origin policy prevents JavaScript from making requests across domains, but the CORS specification allows just the sort of API access you are looking for, and is supported by the current batch of major browsers.

确实,同源策略会阻止 JavaScript 跨域发出请求,但 CORS 规范只允许您正在寻找的那种 API 访问,并且当前批次的主要浏览器都支持。

See how to enable cross-origin resource sharing for client and server:

查看如何为客户端和服务器启用跨域资源共享:

http://enable-cors.org/

http://enable-cors.org/

"Cross-Origin Resource Sharing (CORS) is a specification that enables truly open access across domain-boundaries. If you serve public content, please consider using CORS to open it up for universal JavaScript/browser access."

“跨域资源共享 (CORS) 是一种实现真正跨域开放访问的规范。如果您提供公共内容,请考虑使用 CORS 将其开放以进行通用 JavaScript/浏览器访问。”

回答by Paul Schreiber

This is possible, but you need to use JSONP, not JSON. Stefan's link pointed you in the right direction. The jQuery AJAX pagehas more information on JSONP.

这是可能的,但您需要使用 JSONP,而不是 JSON。Stefan 的链接为您指明了正确的方向。在jQuery的AJAX页面对JSONP的更多信息。

Remy Sharp has a detailed example using PHP.

Remy Sharp 有一个使用 PHP详细示例

回答by zenio

I use Apache server, so I've used mod_proxy module. Enable modules:

我使用 Apache 服务器,所以我使用了 mod_proxy 模块。启用模块:

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so

Then add:

然后加:

ProxyPass /your-proxy-url/ http://service-url:serviceport/

Finally, pass proxy-url to your script.

最后,将 proxy-url 传递给您的脚本。

回答by Jacob Mattison

Browser security prevents making an ajax call from a page hosted on one domain to a page hosted on a different domain; this is called the "same-origin policy".

浏览器安全性防止从一个域上托管的页面到另一个域上托管的页面进行 ajax 调用;这称为“同源策略”。

回答by BillyTom

There are few examples for using JSONP which include error handling.

使用 JSONP 的示例很少,其中包括错误处理。

However, please note that the error-event is not triggered when using JSONP! See: http://api.jquery.com/jQuery.ajax/or jQuery ajax request using jsonp error

但是请注意,使用 JSONP 时不会触发错误事件!请参阅:http: //api.jquery.com/jQuery.ajax/使用 jsonp 错误的 jQuery ajax 请求