【问题标题】:Ajax cross-domain request to REST apiAjax 跨域请求到 REST api
【发布时间】:2015-01-26 22:53:44
【问题描述】:

我在后端有 REST api。我需要发出 ajax 请求来发布一些数据,然后我写:

$(function() { 
    $('#createPin').click(function(e) { 
        e.preventDefault();

var urlAjax = "http://www.agroagro.com/test/v1/register";

$.ajax({
type: "POST",
url: urlAjax,
contentType: "application/x-www-form-urlencoded",
data: {
                    name: "Mile3",
                    email: "new1@new.com",
                    password: "face1book"
                },
  crossDomain:true, 
  success: function(data) { console.log(data); },
error: function(data) {console.log(data); },
dataType: 'json',
beforeSend: function (xhr) {
            xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
        },
        headers: {
            'Access-Control-Allow-Origin': '*'
        }
});


}); 
});

但点击后我得到:

         OPTIONS http://www.agroagro.com/test/v1/register jquery-latest.min.js:4 sendjquery-latest.min.js:4 m.extend.ajaxtest.html:114 (anonymous function)jquery-latest.min.js:3 m.event.dispatchjquery-latest.min.js:3 r.handle

    XMLHttpRequest cannot load http://www.agroagro.com/test/v1/register. Invalid HTTP status code 404

    Object {readyState: 0, getResponseHeader: function, getAllResponseHeaders: function, 

setRequestHeader: function, overrideMimeType: function…}

但是当我尝试在Chrome Advanced Rest Client extension 上运行http://www.agroagro.com/test/v1/register 时,一切正常......如何以及为什么?我的 ajax 请求有什么问题?

查看图片http://i.imgur.com/Ms0oBK9.png - 正如您所见,所有跨域扩展都非常有效。

【问题讨论】:

  • 尝试通过发送源头和用户代理头来伪造请求
  • 请在此处显示示例
  • 记录ajax请求/响应(使用开发者工具中的网络标签)并在这里分享。
  • Chrome Rest 客户端扩展运行良好而我的 ajax 请求未见,这太奇怪了:i.imgur.com/Ms0oBK9.png

标签: jquery ajax rest cross-domain http-status-code-404


【解决方案1】:

您的后端 API 需要返回正确的 CORS 标头。在最简单的变体中,只需让服务器使用此标头回复预检请求(HTTP OPTIONS 动词):

Access-Control-Allow-Origin: *

当您已设置此响应标头时,请注意您的问题显示404 代码(未找到)。当我浏览到http://www.agroagro.com/test/v1/register 时,我也看到了404。不过,这可能仅适用于 GET 请求。

通过将crossDomain 属性设置为true,您是在告诉jQuery 发送一个JSONP 请求。 JSONP 请求通过将<script> 标记嵌入到正文中来工作,这会触发GET 请求。

当服务器配备了正确的 CORS 标头时,您应该禁用 crossDomain。因为,根据 jQuery 文档,如果目标域与当前打开的网页的域不同,crossDomain 默认为 true,请使用此 sn-p:

$.ajax({ 类型:“发布”, 跨域:假, // ... });


对于跨域请求,浏览器会先发送这样的预检请求:

OPTIONS /test/v1/register HTTP/1.1
Host: www.agroagro.com
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://agroagro.com
User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.62 Safari/537.36
Access-Control-Request-Headers: access-control-allow-origin, accept, x-requested-with, content-type
Accept: */*
Referer: http://agroagro.com/test.html
Accept-Encoding: gzip, deflate, sdch
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4

要确定浏览器是否可以发送 POST 请求,请检查服务器响应中的 Access-Control-Allow-Origin 标头。但是,当收到上述请求时,API 服务器会这样回复:

HTTP/1.1 200 OK
Date: Fri, 28 Nov 2014 10:37:18 GMT
Content-Type: text/plain
Content-Length: 0
Connection: keep-alive
Set-Cookie: __cfduid=d57edcdbd0a20a0d11df4dda7c3753d611417171038; expires=Sat, 28-Nov-15 10:37:18 GMT; path=/; domain=.agroagro.com; HttpOnly
Allow: POST,OPTIONS,GET,HEAD
Set-Cookie: PH_HPXY_CHECK=s1; path=/
Cache-control: private
Server: cloudflare-nginx
CF-RAY: 1905edebcdb50f69-FRA

如您所见,OPTIONS 请求没有返回 Access-Control-Allow-Origin 标头。

解决方案:让 AP​​I 端点不仅为 POST 请求返回 Access-Control-Allow-Origin 标头,还为预检 OPTIONS 请求返回。

【讨论】:

  • 但是我把那个标头放到了后端......还有 chrome 扩展如何能很好地工作并发送好的数据?
  • 好的,是的,但这是开发人员可以像那样工作的支持的东西......但是尝试使用 Chrome 休息扩展程序然后工作正常,同样的托管请求也工作正常
  • @LaraBeginer — chrome 扩展是安装在用户浏览器中的软件,并被授予访问任意其他网站的权限。你的 JavaScript 不是。
  • 我再次得到:XMLHttpRequest 无法加载agroagro.com/test/v1/register。请求的资源上不存在“Access-Control-Allow-Origin”标头。因此不允许访问 Origin 'agroagro.com'。
  • @Quentin 但 Chrome 扩展也发送跨域请求
【解决方案2】:

从您的服务器发送以下标头

Access-Control-Allow-Origin : THE SITE FROM WHICH YOU WILL MAKE THE AJAX REQUEST
Access-Control-Allow-Credentials : true

然后在jquery中添加以下代码

xhrFields: {withCredentials: true }

【讨论】:

  • 是的,但我不知道哪个域将是因为我创建了 mobile phonegap 应用程序并且该应用程序没有 url
  • 我添加了 header: header("Access-Control-Allow-Credentials : true");但又是一样的
  • 如果请求是从移动应用程序发送的,那么你不需要像Access-Control-Allow-Origin 这样的东西,但是如果你从一些基于网站的 IDE 发送请求,那么你需要担心所有的事情。我认为您正在通过基于 Web 的 IDE 测试应用程序,对吗?
  • 我从浏览器测试应用程序...请转到:agroagro.com/test.html 并单击按钮然后查看控制台
  • 这就是重点。从移动设备而不是典型的网络浏览器运行它
猜你喜欢
  • 2023-03-21
  • 2013-03-06
  • 1970-01-01
  • 1970-01-01
  • 2012-04-23
  • 2015-06-05
  • 2013-11-25
  • 2013-08-20
相关资源
最近更新 更多