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

时间:2012-04-25 10:58:00

标签: javascript ajax google-chrome same-origin-policy cors

我有一个适用于GET的网络服务。要访问此Web服务,需要传递一些自定义标头。

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

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

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

OPTIONS调用将状态返回为401。

我怀疑这是因为我的网络服务仅支持GET。我该如何解决这个问题? 请帮助。 (我的代码适用于IE,但不能与其他浏览器一起使用,例如Chrome)

1 个答案:

答案 0 :(得分:4)

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

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

    Access-Control-Allow-Methods: GET, OPTIONS
    
  2. 请求发送的自定义标头是否允许返回浏览器? 例如:

    Access-Control-Allow-Headers: X-PINGOTHER 
    
  3. 远程服务器必须在任何安全的,符合标准的浏览器(即不是旧版本的IE)之前返回这两个(并且绝大多数是第二个),才能允许非原始响应通过。

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

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

    如果您运行的是Apache 2.0,则在2.2上附加标题的语法为add,请使用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文件以仅在适当时返回标头,而不是对该目录的所有请求。