避免使用 CORS 预检选项以获得更好的性能

Posted

技术标签:

【中文标题】避免使用 CORS 预检选项以获得更好的性能【英文标题】:Avoid CORS preflight OPTIONS for better performance 【发布时间】:2017-07-07 21:48:19 【问题描述】:

使用 CDN 提供商并像这样从 CDN 调用静态 html 文件。

          $.ajax(
            url : CDNPATH,
            type : "GET",
            contentType : "text/plain; charset=utf-8",
            async : async,
            cache : true,
            processData : false,
            success : function(response, status, xhr) 
                onSuccess(response, status, xhr);
                $(document).trigger('contentReady');
            
        );

在应用程序的主页上,我有 5 个触发 5 个 OPTION 调用的静态 HTML 文件。可以想象,它会损害性能。我在类似的问题上看到可以使用GET 方法和text/plain 来避免这种情况,我按照上面的方法做了,但是没有用。

如何避免这些预检 OPTIONS 方法?

【问题讨论】:

您的浏览器发送的请求标头到底是什么?您可以将它们添加到问题中吗? 只有批准的请求和响应标头的简单 GET 应避免 OPTIONS 请求。 (我只是向自己证明了这一点。)我刚刚检查了使用 jQuery v3.1.1 的 $.ajax 调用,它没有触发预检,所以我认为它可能是来自的响应标头你的 CDN 使它成为必要......(顺便说一句:你不需要 contentType,你没有向服务器发送数据。) 我仍然对试图找出触发预检的原因感到好奇,但是由于无法看到客户端代码最终在请求中发送的确切请求标头,我们只是在玩一个猜谜游戏。 如果我在此处发布域,您介意检查一下吗? @sideshowbarker @DarthVader 是的,如果您有更多信息要发布,我很乐意为您提供帮助——我相信这里的其他人也是如此 【参考方案1】:

也许charset 参数的存在导致了预检?根据规范,浏览器是 required to ignore any params and only consider the MIME type,但可能它们不符合规范。

一个 CORS 安全列表的请求标头是一个标头,其名称是一个

Accept Accept-Language Content-Language Content-Type,其值在解析后的 MIME 类型(忽略参数)为 application/x-www-form-urlencodedmultipart/form-datatext/plain

否则,我看不出您的请求中的哪些内容会触发预检。也许我错过了什么……


2017-02-20 更新

好的,基于information provided in a comment above,该网站的源似乎包含一个带有此内容的script元素:

window["_tsbp_"] =  ba : "X-TS-BP-Action", bh : "X-TS-AJAX-Request";

...我还没有单步执行其余代码来查看它有什么效果,但它似乎导致 X-TS-AJAX-Request 标头被添加到 XHR 请求中,从而触发了预检。


我想这里的一般要点是:每当您发现一个请求正在触发浏览器进行预检但您不知道原因时,故障排除步骤编号可能应该是使用您的浏览器开发工具来准确找出什么请求您的代码导致发送的标头。

【讨论】:

我在本地尝试了带有跨域请求的 OP 的 $.ajax 调用(包括 charset)。没有触发 OPTIONS。添加一个未经批准的标题确实如此。所以我想知道它是否是来自 CDN 的响应标头,但是... 我从 contentType 中删除了字符集,但仍然看到 OPTIONS 方法:( 浏览器仅根据客户端代码设置的标头评估预检需求。因此,据我所知,CDN 添加的标头不会触发预检。一定是别的东西。 @T.J.Crowder 我现在意识到您的意思一定是 CDN 将标头注入到浏览器运行的客户端代码中。至少这似乎是添加 X-TS-AJAX-Request 标头时发生的情况。 @sideshowbarker:我不是那个意思,不。我看不出 CDN 如何修改浏览器代码。听起来像是浏览器扩展或 ajaxStart 处理程序在 OP 代码中添加标头。

以上是关于避免使用 CORS 预检选项以获得更好的性能的主要内容,如果未能解决你的问题,请参考以下文章

使用 CORS 避免预检 OPTIONS 请求

如何避免文件上传时的 CORS 预检请求?

如何避免单页应用程序中的 CORS 预检请求?

是否可以手动预检多个 CORS 资源?

Angular从客户端避免CORS问题

移动应用程序避免或保护 CORS?