Restify和Angular CORS请求的资源上没有“Access-Control-Allow-Origin”标头

时间:2014-01-06 20:40:11

标签: javascript cors restify

在使用承载令牌授权类型保护Restify实现REST api时,我遇到了这个问题。

当我向API服务器发送简单的get请求时,它失败并出现CORS问题

  

405(方法不允许)angular.js:7962

     

选项http://api.host.com/tests没有'Access-Control-Allow-Origin'标题   出现在请求的资源上。来源'http://local.host.com'是   因此不允许访问。


在我的回答中描述了解决方案,所以这对我来说不是真正的问题,因为我已经知道了答案后放了它,但希望它将来会为其他人节省时间。

2 个答案:

答案 0 :(得分:21)

因为解决问题所面临的问题是内部CORS模块管理CORS逻辑。在此模块中,您可以找到允许的标头列表,默认情况下是

[
        'accept',
        'accept-version',
        'content-type',
        'request-id',
        'origin',
        'x-api-version',
        'x-request-id'
]

正如我在问题中所说,我使用了承载令牌身份验证,因此我使用Authorization标头发送了我的请求。它不包含在默认列表中,这就是我的请求失败的原因。

要解决该问题,我们需要将此标头添加到ALLOW_HEADERS列表中。在我的restify配置代码中,我添加了这一行:

restify.CORS.ALLOW_HEADERS.push('authorization');

如果您遇到类似的问题,请认为信息可能会有所帮助,因为我花了很多钱来寻找解决方案。

答案 1 :(得分:6)

由于same-origin policy,您将无法访问http://api.host.com/tests部署的文件中的网址http://local.host.com


由于源(来源)页面和目标网址位于不同的域,您的代码实际上是在尝试发出 Cross-domain (CORS)请求(因此 {{ 1}} - 请参阅下面的说明),而不是普通的OPTIONS

简而言之,同源政策强制要求浏览器只允许对同一域中的服务进行Ajax调用,而不是HTML页面。


示例: GET中的页面只能直接请求http://www.example.com/myPage.html中的服务,例如http://www.example.com。如果该服务位于其他域中,则浏览器不会进行直接调用(如您所期望的那样)。相反,它会尝试发出CORS请求。

简而言之,要执行CORS请求,请使用浏览器:

  • 首先会向目标网址发送http://www.example.com/testservice/etc个请求
  • 然后仅当服务器对该OPTION的响应包含允许CORS请求的adequate headers (Access-Control-Allow-Origin is one of them)时,浏览才会执行调用(几乎完全按照它的方式执行如果HTML页面位于同一个域中。)

如果预期的标头没有出现在OPTIONS中,浏览器将放弃,通知错误(它尝试了CORS请求并且没有找到必要的标头)。

如何解决?

  • 将目标服务放在原始页面的同一个域中;或
  • 在服务器上启用CORS(启用必要的标头);或
  • 如果您没有服务器的服务器端访问权限,您也可以镜像它(在您拥有的服务器中创建它的副本)。
  • 如果您只是想要请求信息,
  • JSONP也是一个解决方案(但这也需要服务器端访问设置)。