前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >理解跨域资源共享

理解跨域资源共享

作者头像
madneal
发布2019-11-28 21:41:54
1.1K0
发布2019-11-28 21:41:54
举报
文章被收录于专栏:madMenmadMen

原文:Understanding CORS 译者:neal1991 welcome to star my articles-translator, providing you advanced articles translation. Any suggestion, please issue or contact me LICENSE: MIT

CORS 或跨域资源共享是一种 http 机制,它允许用户通过使用一些额外的头来访问别的域的资源。例如,假设位于http://test1.domain.com上的应用程序需要对位于 http://test2.domain.com/some/awesome/endpoint上的 api 进行 REST 调用。

现在默认情况下,浏览器不允许这样的请求。这是出于 http 安全原因考虑。这意味着浏览器不允许从网页上的脚本中发出的请求访问位于除最初加载的网站之外的域上的任何 HTTP 资源。例如,XMLHttpRequest 和Fetch API 都遵循同源策略。这就是 CORS 的用武之地。CORS 通过首先使用一些特殊的头来验证test2.domain.com来实现。

和 CORS 相关的头包括

请求头

  • Origin
  • Access-Control-Request-Method
  • Access-Control-Request-Headers

响应头

  • Access-Control-Allow-Origin
  • Access-Control-Allow-Credentials
  • Access-Control-Expose-Headers
  • Access-Control-Max-Age
  • Access-Control-Allow-Methods
  • Access-Control-Allow-Headers

功能概述

CORS 工作的方式是:

  1. 浏览器遇到一个发送给 test2.domain.com 的请求。
  2. 它会检查这个请求是否是 GET 或者 HEAD,如果是的话,它将会查找任意自定义 HTTP 头。如果发现任意一个,它将会转到步骤3,否则它会继续处理真实请求,比如步骤 7.
  3. 浏览器将会使用 Origin, Access-Control-Request-Method * 以及 *Access-Control-Request 头向 test2.domain.com 发送一个 OPTIONS 请求。
  4. test2.domain.com 必须现在响应合适的 Access-Control- 头。
  5. 如果在 OPTIONS 请求的响应头中没有发现合适的 Access-Control- 头的话就会错误终止。
  6. 如果在 OPTIONS 请求的响应头中发现合适的 Access-Control- 头的话就会继续步骤 7。
  7. 发送真正的请求。

实现

现在,如果test2.domain.com是一个 api 网关,我们可以通过在网关设置中启用 CORS 选项使其与 CORS 兼容。但是,如果你发现自己处于域甚至网关不支持此功能的情况下,请不要担心,仍有一种方法。

你可以在 F5 通过创建 iRule 来插入这些自定义头让test2.domain.com CORS 兼容。

代码语言:javascript
复制
when HTTP_REQUEST priority 200 {    unset -nocomplain cors_origin    if { ( [HTTP::header Origin] contains "test1.domain.com" ) } {        if { ( [HTTP::method] equals "OPTIONS" ) and ( [HTTP::header exists "Access-Control-Request-Method"] ) } {            # CORS preflight request - return response immediately            HTTP::respond 200 "Access-Control-Allow-Origin" [HTTP::header "Origin"] \                              "Access-Control-Allow-Methods" "POST, GET, OPTIONS" \                              "Access-Control-Allow-Headers" [HTTP::header "Access-Control-Request-Headers"] \                              "Access-Control-Max-Age" "86400" \                              "Access-Control-Allow-Credentials" "true"        } else {            # CORS GET/POST requests - set cors_origin variable            set cors_origin [HTTP::header "Origin"]                log local0. "Requested hostname: [HTTP::host] from IP: [IP::local_addr]"                }        }}when HTTP_RESPONSE {    # CORS GET/POST response - check cors_origin variable set in request    if { [info exists cors_origin] } {        HTTP::header remove Access-Control-Allow-Origin        HTTP::header remove Access-Control-Allow-Credentials        HTTP::header remove Vary        HTTP::header insert "Access-Control-Allow-Origin" $cors_origin        HTTP::header insert "Access-Control-Allow-Credentials" "true"        HTTP::header insert "Vary" "Origin"   }

这样就可以了.

特殊的例子

我在使用 CORS 时发现了一个非常有趣的案例,我认为这可能值得一提。设置是这样的,我有一个在 domaina 托管的网站。它需要在 domainb 上托管的资源。现在 domain_b 是一个 API 网关,我在网关上启用了开箱即用的 CORS 功能,并认为这样就可以了。我发现除了一个对网关后面的 websphere 服务器上托管的应用程序的资源特殊调用之外,所有对网关的调用都是通过的,这个调用是在。该调用总是错误地出现相同的之前的 CORS 错误:

代码语言:javascript
复制
    No 'Access-Control-Allow-Origin' header is present on the request resource. Origin '[http://test1.domain.com](http://test1.domain.com/)' is therefore not allowed access.

仔细观察,可以发现响应头中已经丢失了 Access-Control-* 。现在,Websphere 带有自己的 http 服务器,结果证明 http 服务器占用了访问控制头。基于此可以很容易地通过修改 websphere上的 http.conf 来修复。

因此,如果你遇到类似这样的问题,请始终确保验证你的基础架构中是否有任何基础 http/Web服务器。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-08-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 madMen 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 功能概述
  • 实现
  • 特殊的例子
相关产品与服务
API 网关
腾讯云 API 网关(API Gateway)是腾讯云推出的一种 API 托管服务,能提供 API 的完整生命周期管理,包括创建、维护、发布、运行、下线等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档