如何从 Web 服务提供飞行前请求

Posted

技术标签:

【中文标题】如何从 Web 服务提供飞行前请求【英文标题】:how to serve pre-flight request from web service 【发布时间】:2012-05-06 01:18:28 【问题描述】:

我有一个在GET 上运行的网络服务。要访问此 Web 服务,需要传递一些自定义标头。

当我尝试使用 GET 方法从 javascript 代码访问 Web 服务时,请求方法正在更改为 OPTIONS。 (域名不同)

我阅读了一些文章,发现带有自定义标头的请求将被预先发送,在这种情况下,在实际方法调用之前,将向服务器发出带有 OPTIONS 方法的请求。

但我的问题是在OPTIONS 调用之后,真正的方法(即GET)没有被调用。

OPTIONS 调用返回的状态为 401。

我怀疑这是因为我的网络服务只支持GET。我该如何解决这个问题? 请帮忙。 (我的代码在 IE 上运行良好,但在其他浏览器(例如 Chrome)上运行良好)

【问题讨论】:

根据你的例子,我会更担心 IE is 允许请求。 我必须让这些东西在 chrome 或其他浏览器上运行。因为最后我必须使用智能手机浏览器来完成这些事情。 这种情况下,请确认手机浏览器是否支持CORS。这是一个很好的列表:caniuse.com/cors 【参考方案1】:

需要检查两件事(不知道您的服务器端语言/技术是什么):

    您是否在您的Access-Control-Allow-Methods 中包含OPTIONS 作为有效方法?示例:

    Access-Control-Allow-Methods: GET, OPTIONS
    

    您的请求发送的自定义标头是否被允许返回到浏览器? 示例:

    Access-Control-Allow-Headers: X-PINGOTHER 
    

远程服务器必须返回这两个(并且肯定是第二个),然后任何安全、符合标准的浏览器(即不是旧版本的 IE)才会允许非源响应通过。

因此,如果您想在 HTTP 服务器级别实现此功能并保持 Web 服务的可移植性,您可以尝试以下方法:

我们假设您的网络服务 URL 是 http://example.org/service,服务路径是 /srv/www/service

如果您运行的是 Apache 2.0,附加标头的语法是 add,在 2.2 上,使用 set

所以,你可以修改/srv/www/service/.htaccess

 Header set Access-Control-Allow-Methods "GET, OPTIONS"
 Header set Access-Control-Allow-Headers "X-MY_CUSTOM_HEADER1,X-MY_CUSTOM_HEADER2"
 Header set Access-Control-Allow-Origin "*"

当然,mod_headers Apache 模块需要开启才能使上述工作正常进行。此外,将 allow-origin 设置为通配符是有风险的,如果您发送 Access-Control-Allow-Credentials: true 标头(在这种情况下不能使用通配符),它实际上会导致请求失败。此外,使用 Apache 的 SetEnvIf mod,您可以微调 htaccess 文件以仅在适当时返回标头,而不是针对该目录的所有请求。

【讨论】:

但我有一个 cxf 网络服务。你是说我必须允许这些方法使用 OPTIONS 和 GET 一起工作? @GET @Produces( "application/json" ) @Path("/getData") public CustomDTO getData() ... 网络服务应该无关紧要。您是否使用 Apache 作为实际的 HTTP 服务器(在提供 Web 服务之前管理 HTTP 标头)?如果是这样,您应该能够修改(我认为在 .htaccess 文件中)请求的处理和响应方式。 所以,Web 服务代码不会有任何变化。必须将 Web 服务器配置为处理预检请求。我说的对吗? 我正在使用带有 apache CXF 引擎的 tomcat 6.0 来创建 Web 服务。如何处理预检 OPTION 请求?

以上是关于如何从 Web 服务提供飞行前请求的主要内容,如果未能解决你的问题,请参考以下文章

当提供商因缺少授权标头而拒绝飞行前请求时,让客户端 CORS 工作

如果请求来自 VueJS,NodeJs Passport 执行 CORS 飞行前

调用.net web api时,Angular Delete方法不传递飞行前请求

如何在浏览器的控制台中查看 CORS 飞行前 OPTIONS 请求?

多个 CORS 适用于 GET 但不适用于 PUT/POST 与飞行前请求 Web api 2

未触发 CORS 检查的飞行前请求