我在本地局域网(machineA)上有一台机器,它有两个web服务器。第一个是XBMC中的内置程序(在端口8080上),它显示我们的库。第二个服务器是一个CherryPy python脚本(端口8081),我用它按需触发文件转换。文件转换由XBMC服务器提供的页面的AJAX POST请求触发。

转到http://machineA:8080,显示库 显示Library。 用户单击“转换”链接,发出以下命令-

jQuery Ajax请求

$.post('http://machineA:8081', {file_url: 'asfd'}, function(d){console.log(d)})

浏览器发出一个带有以下报头的HTTP OPTIONS请求;

请求头- OPTIONS

Host: machineA:8081
User-Agent: ... Firefox/4.01
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Origin: http://machineA:8080
Access-Control-Request-Method: POST
Access-Control-Request-Headers: x-requested-with

服务器响应如下;

响应头- OPTIONS (STATUS = 200 OK)

Content-Length: 0
Access-Control-Allow-Headers: *
Access-Control-Max-Age: 1728000
Server: CherryPy/3.2.0
Date: Thu, 21 Apr 2011 22:40:29 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS
Content-Type: text/html;charset=ISO-8859-1

然后谈话就停止了。理论上,浏览器应该在服务器响应正确的(?)时发出POST请求。CORS报头(Access-Control-Allow-Origin: *)

为了排除故障,我还发布了相同的$。从http://jquery.com发布命令。这就是我难住的地方,从jquery.com, post请求工作,OPTIONS请求被post发送。来自该事务的标题如下;

请求头- OPTIONS

Host: machineA:8081
User-Agent: ... Firefox/4.01
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Origin: http://jquery.com
Access-Control-Request-Method: POST

响应头- OPTIONS (STATUS = 200 OK)

Content-Length: 0
Access-Control-Allow-Headers: *
Access-Control-Max-Age: 1728000
Server: CherryPy/3.2.0
Date: Thu, 21 Apr 2011 22:37:59 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS
Content-Type: text/html;charset=ISO-8859-1

请求头- POST

Host: machineA:8081
User-Agent: ... Firefox/4.01
Accept: */*
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://jquery.com/
Content-Length: 12
Origin: http://jquery.com
Pragma: no-cache
Cache-Control: no-cache

响应头- POST (STATUS = 200 OK)

Content-Length: 32
Access-Control-Allow-Headers: *
Access-Control-Max-Age: 1728000
Server: CherryPy/3.2.0
Date: Thu, 21 Apr 2011 22:37:59 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS
Content-Type: application/json

我不明白为什么同样的请求在一个站点上可以工作,而在另一个站点上就不行。我希望有人能指出我错过了什么。谢谢你的帮助!


当前回答

要求:

 $.ajax({
            url: "http://localhost:8079/students/add/",
            type: "POST",
            crossDomain: true,
            data: JSON.stringify(somejson),
            dataType: "json",
            success: function (response) {
                var resp = JSON.parse(response)
                alert(resp.status);
            },
            error: function (xhr, status) {
                alert("error");
            }
        });

回应:

response = HttpResponse(json.dumps('{"status" : "success"}'))
response.__setitem__("Content-type", "application/json")
response.__setitem__("Access-Control-Allow-Origin", "*")

return response

其他回答

如果由于某些原因,在尝试添加报头或设置控制策略时,你仍然没有得到任何地方,你可以考虑使用apache ProxyPass…

例如,在一个使用SSL的<VirtualHost>中添加以下两个指令:

SSLProxyEngine On
ProxyPass /oauth https://remote.tld/oauth

确保加载了以下apache模块(使用a2enmod加载它们):

代理 proxy_connect proxy_http

显然,为了使用apache代理,你必须改变你的AJAX请求url…

我解决了自己的问题时使用谷歌距离矩阵API通过设置我的请求头与Jquery ajax。看看下面的内容。

var settings = {
          'cache': false,
          'dataType': "jsonp",
          "async": true,
          "crossDomain": true,
          "url": "https://maps.googleapis.com/maps/api/distancematrix/json?units=metric&origins=place_id:"+me.originPlaceId+"&destinations=place_id:"+me.destinationPlaceId+"&region=ng&units=metric&key=mykey",
          "method": "GET",
          "headers": {
              "accept": "application/json",
              "Access-Control-Allow-Origin":"*"
          }
      }

      $.ajax(settings).done(function (response) {
          console.log(response);

      });

注意我在设置中添加了什么 **

"headers": {
          "accept": "application/json",
          "Access-Control-Allow-Origin":"*"
      }

** 我希望这能有所帮助。

结合Laravel解决了我的问题。只需将此头添加到您的jquery请求Access-Control-Request-Headers: x-requested-with,并确保您的服务器端响应具有此头设置Access-Control-Allow-Headers: *。

以下是对我有用的方法的总结:

定义一个新函数(包装为$。简化Ajax):

jQuery.postCORS = function(url, data, func) {
  if(func == undefined) func = function(){};
  return $.ajax({
    type: 'POST', 
    url: url, 
    data: data, 
    dataType: 'json', 
    contentType: 'application/x-www-form-urlencoded', 
    xhrFields: { withCredentials: true }, 
    success: function(res) { func(res) }, 
    error: function() { 
            func({}) 
    }
  });
}

用法:

$.postCORS("https://example.com/service.json",{ x : 1 },function(obj){
      if(obj.ok) {
           ...
      }
});

也可以和.done,.fail等一起使用:

$.postCORS("https://example.com/service.json",{ x : 1 }).done(function(obj){
      if(obj.ok) {
           ...
      }
}).fail(function(){
    alert("Error!");
});

服务器端(在这个例子中,example.com是托管的),设置这些头(添加了一些PHP示例代码):

header('Access-Control-Allow-Origin: https://not-example.com');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 604800');
header("Content-type: application/json");
$array = array("ok" => $_POST["x"]);
echo json_encode($array);

这是我所知道的从JS真正POST跨域的唯一方法。

JSONP将POST转换为GET,后者可能在服务器日志中显示敏感信息。

我有完全相同的问题,jquery ajax只给了我在post请求的cors问题得到请求工作得很好-我累了上面的一切没有结果。我有正确的头在我的服务器等。改用XMLHTTPRequest而不是jquery立即解决了我的问题。无论我使用哪个版本的jquery,它都没有修复它。如果不需要向后兼容浏览器,Fetch也可以正常工作。

        var xhr = new XMLHttpRequest()
        xhr.open('POST', 'https://mywebsite.com', true)
        xhr.withCredentials = true
        xhr.onreadystatechange = function() {
          if (xhr.readyState === 2) {// do something}
        }
        xhr.setRequestHeader('Content-Type', 'application/json')
        xhr.send(json)

希望这能帮助其他有同样问题的人。