jQuery AJAX 调用导致错误状态403

4zcjmb1e  于 2023-05-17  发布在  jQuery
关注(0)|答案(3)|浏览(293)

我正在使用jQuery AJAX 对Web服务进行查询。我的查询看起来像这样:

var serviceEndpoint = 'http://example.com/object/details?version=1.1';
$.ajax({
  type: 'GET', 
  url: serviceEndpoint,
  dataType: 'jsonp',
  contentType: 'jsonp',
  headers: { 'api-key':'myKey' },
  success: onSuccess,
  error: onFailure
});

当我执行这个命令时,我得到一个状态错误403。我不明白为什么我的呼叫结果是状态代码403。我控制着我的服务的安全性,它被标记为完全开放。我知道密钥是有效的,因为我正在另一个调用中使用它,这是有效的。下面是起作用的调用:

var endpoint = 'http://example.com/object/data/item?version=1.1';
$.ajax({ 
  type: 'POST', 
  url: endpoint, 
  cache: 'false',
  contentType:'application/json',
  headers: {
    'api-key':'myKey',
    'Content-Type':'application/json'
  },
  data: JSON.stringify({
    id: 5,
    count:true
  }),
  success: onDataSuccess,
  error: onDataFailure
});

我知道这是两个不同的终点。但我100%确信这不是服务器端身份验证或权限错误。再一次,服务器端的一切都是开放的。这意味着我在客户端请求上犯了一些错误。
我觉得我应该告知在开发过程中提出了此请求。所以,我从http://localhost:3000运行这个。因此,我立即认为这是一个CORS问题。但看起来一切正常。事实上,我的POST请求工作,但我的GET不让我绝对沮丧。我错过什么了吗?会是什么呢?

vlf7wbxs

vlf7wbxs1#

403错误的原因是您没有发送标头。由于您正在发出CORS请求,因此无法发送任何自定义头,除非服务器通过向响应添加Access-Control-Allow-Headers来启用这些头。
在preflighted-request中,客户端向服务器发出2个请求。第一个是preflight(使用OPTIONS方法),第二个是真实的的请求。服务器发送Access-Control-Allow-Headers报头作为预检请求的响应。所以它允许发送一些头。通过这种方式,您的POST请求可以工作,因为POST请求是一个preflight请求。但是对于GET请求,没有preflight来收集Access-Control-Allow-Headers头,并且浏览器在这种情况下不会发送您的自定义头。

解决此问题的方法:

作为解决方法,将dataTypecontentType设置为json,如下所示:

var serviceEndpoint = 'http://example.com/object/details?version=1.1';
$.ajax({
  type: 'GET', 
  url: serviceEndpoint,
  dataType: 'json',
  contentType: 'json',
  headers: { 'api-key':'myKey' },
  success: onSuccess,
  error: onFailure
});

通过这种方式,您的get请求将是preflighted request。如果您的服务器启用了api-key与Access-Control-Allow-Headers头,它将工作。
上面请求的示例服务器配置(用express.js编写):

res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', '*');
res.setHeader('Access-Control-Allow-Headers', 'api-key,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);

添加:
实际上,在执行jsonp请求时,contentType应该是application/javascriptapplication/json。没有contentType作为jsonp

5tmbdcev

5tmbdcev2#

如果您查看jQuery的 AJAX 调用的API page,它在Content-Type部分中提到了以下内容:

**注意:**对于跨域请求,将内容类型设置为application/x-www-form-urlencoded、multipart/form-data或text/plain以外的任何类型都会触发浏览器向服务器发送preflight OPTIONS请求。

该页面并没有真正提到什么是“飞行前选项请求”,但我在网上查找该短语时发现了一些有趣的链接:

有趣的是代码示例& HTML5 Rocks页面上的CORS图像。该图显示了 AJAX 调用是如何从JavaScript代码到浏览器再到服务器的,以及响应是如何在这三个代码之间往返的。
我们倾向于认为JavaScript +浏览器=客户端,但在插图中,作者解释了Web开发人员的代码与浏览器开发人员的代码之间的区别,前者是用JavaScript代码编写的,但后者是用C,C++或C#代码编写的。
一个好的包分析器工具是Fiddler,它类似于Wireshark。这些工具中的任何一个都应该向您显示从浏览器发送到服务器的pre-flight请求。最有可能的情况是,服务器在那里用403 Forbidden error阻塞了 AJAX 请求。

pw9qyyiw

pw9qyyiw3#

另请参阅this post,它讨论了Google翻译扩展将无关的HTML附加到某些页面元素的问题。
例如,在上面链接的案例中,Google翻译追加了以下行

<p>&nbsp;</p>
<div id="gtx-trans" style="position: absolute; left: -28px; top: -8px;">&nbsp;</div>

到TinyMCE编辑器内容。当用户输入的数据被发送到后端时,它包括Google翻译添加,这导致了403错误。

相关问题