为啥添加额外的标头会导致 AJAX 调用失败

Posted

技术标签:

【中文标题】为啥添加额外的标头会导致 AJAX 调用失败【英文标题】:Why is adding an extra header making the AJAX call fail为什么添加额外的标头会导致 AJAX 调用失败 【发布时间】:2017-06-10 19:14:02 【问题描述】:

AJAX 调用:

$.ajax(
    url: "http://myserver2:296/api/Demo/HelloWorld",
    type: "GET",
    dataType: 'JSONP',
    jsonp: "callback",
    headers:  'API_KEY': 'mykey09090' ,
    success: function (result) 
        console.log(result);
    ,
    error: ajaxFailed
);

function ajaxFailed(xmlRequest) 
    alert(xmlRequest.status + ' \n\r ' +
          xmlRequest.statusText + '\n\r' +
          xmlRequest.responseText);

我收到以下错误:Failed to load resource: the server responded with a status of 403 (Forbidden)。但是,当我使用 Postman 时,我只需添加带有 http://myserver2:296/api/Demo/HelloWorld url 的标题,它就会返回字符串。

我能否获得一些帮助来解决这个问题。

我的目标是允许源服务器连同正确提供的 API 密钥从 Web Api 获取数据。

【问题讨论】:

API_KEY 和它的值在 AJAX 请求中会去哪里?是data还是其他方式? How can I add a custom HTTP header to ajax request with js or jQuery?的可能重复 我试过了,不幸的是它对我不起作用。我仍然收到Failed to load resource: the server responded with a status of 403 (Forbidden) 错误 添加 CORS 是否足够安全,或者我还需要额外的安全性吗? 我发现了另一个可能的重复项。 ***.com/questions/5750696/… 。我会在 ajax 中设置 crossDomain 选项。如果那不是发送 cors 标头。手动添加 cors 标头,就像您是 api 密钥一样 【参考方案1】:

API_KEY 标头添加到请求triggers your browser to first send a CORS preflight OPTIONS request。 任何您添加到请求中的标头(定义为CORS-safelisted request-headers 的标头除外)都会触发您的浏览器发送 CORS 预检 OPTIONS 请求。

我无法确定,但您看到的 403 似乎来自您的服务器响应该 OPTIONS 请求,并说它不希望收到 OPTIONS 请求并且不允许它们。

您没有从 Postman 获得此信息的原因是,与浏览器引擎不同,Postman 不实现 CORS,因此它不发送 OPTIONS 请求。 (Postman 不在浏览器为 Web 应用程序强制实施的同源 Web 安全模型下运行。)

因此,要使您的客户端应用程序按预期工作以通过脚本跨域访问该服务器,您必须将服务器配置为以正确的方式响应该 CORS 预检 OPTIONS 请求。

【讨论】:

感谢您的回复。为什么它在没有 API-KEY 的情况下工作是有道理的……最后一部分有任何帮助或指南吗?拥有 CORS 是否使其在一定程度上或很多方面安全? 你说的配置服务器是指我的API? 是的,通过配置服务器,我的意思是无论服务器端的 .asax 和 .cs 等代码是暴露 API 的。 & 2/ 如果在该 Intranet/firewall 内,仅通过假设用户是否在 Intranet/firewall 内具有 IP 地址来限制对资源的访问,那么他们可以访问该资源。如果不是这种情况,那么使用限制性 CORS 将一无所获。如果您对资源进行其他身份验证,您也不会从添加 CORS 限制中获益。 感谢您的步骤。至于您的第一条评论,是否有关于如何逐步实现它的指南?另外,如果我根据评论做了需要做的事情,我可以删除 cors?

以上是关于为啥添加额外的标头会导致 AJAX 调用失败的主要内容,如果未能解决你的问题,请参考以下文章

为啥将自定义 WrappedRequest 与额外的类型参数和 ActionFilter 组合会导致类型丢失?

PHP:为啥强制 mime 下载会添加 2 个额外的空行?

为啥 str(KeyError) 添加额外的引号?

为啥在 Playstore 上发布我的应用程序后,firebase 会添加一个额外的日历节点?

为啥浏览器会忽略 set-cookie 标头,并且未使用 fetch 从 Ajax 调用中保存 cookie?

当通过Ajax进行POST时,Laravel 5.6 CSRF令牌失败