首页 > 作文

Yii支持多域名cors原理的实现

更新时间:2023-04-06 16:39:04 阅读: 评论:0

平常我们遇到跨域问题时,常使用 cors(cross-origin resource sharin)方式解决。不知你是否注意到,在设置响应头 access-control-allow-origin 域的值时,只允许设置一个域名,这意味着不能同时设置多个域名来共享资源。而在 yii2 中直接使用'origin' => ['http://www.site1.com', 'http://www.site2.com']的形式却可以设置多个 cors 域名值,why?

动名词做主语的用法

其实,yii2 中采用了动态设置 access-control-allow-origin 域值的方法来解决这个问题。

说明:测试使用的接口域名
api.d.fanhaobai.com,cros 多域名为
www.d.yii.com
www.fq.yii.com

nginx设置多域名

尝试直接通过 nginx 的add_header模块追加 access-control-allow-origin 值实现,如下:

add_header access-control-allow-origin http://www.fq.yii.com;add_header access-control-allow-origin http://www.d.yii.com;

接口 请求 和 响应头 如下:

respon headersaccess-control-allow-origin: http://www.fq.yii.comaccess-control-allow-origin: http://www.d.yii.comconnection: keep-alivecontent-type: application/json; chart=utf-8... ...request headersaccept: */*accept-encoding: gzip, deflateaccept-language: zh-cn,zh;q=0.8host: api.d.fanhaobai.comorigin: http://www.fq.yii.comproxy-connection: keep-alive... ...

当前域为www.fq.yii.com,需跨域请求http://api.d.fanhaobai.com/v1/config/list.json的资源。浏览器抛出如下跨域错误:

xmlhttprequest cannot load http://api.d.fanhaobai.com/v1/config/list.json. the ‘access-control-allow-origin’ header contains multiple values ‘http://www.fq.yii.com, http://www.d.yii.com’, but only one is allowed. origin ‘http://www.fq.yii.com’ is therefore not allowed access.

以上信息明确说明,access-control-allow-origin 只能设置为一个值,即每次请求只能对应一个域名值。故通过该方法不能设置多域名进行 cors。

yii2设置多域名

yii2 设置多域名 cors,只需在对应控制器(configcontroller)中设置 cors 行为,如下:

class bacontroller extends controller{  /**   * @inheritdoc   */  public function behaviors()  {    return [      'corsfilter' => [        'class' => \yii\filters\cors::classname(),        'cors' => [          //运行cors域名列表          'origin' => ['http://www.d.yii.com', 'http://www.fq.yii.com'],  放下顾虑        'access-control-allow-credentials' => true,        ]      ],    ];  }}

重新在www.fq.yii.com发送 cors 请求,发现此时已经不存在跨域问题。响应头 如下:

access-control-allow-credentials: trueaccess-control-allow-origin: http://www.fq.yii.comconnection: keep-alivecontent-type: application/json; chart=utf-8... ...

我们会发现,access-control-allow-origin 域的值为http://www.fq.yii.com,刚好为当前域名一致,且只有一个值,并未出现设置的http://www.d.yii.com值。

同时,在www.d.yii.com下发送 cors 请求,也不存在跨域问题。响应头中 access-control-allow-origin 值为http://www.d.yii.com

由此可知,yii2 在控制器行为中设置 origin 项,只是一个域名白名单,而返回的 access-control-allow-origin 同请求的域名一致且在这个白名单中,这个 access-control-allow-origin 由 yii2 根据当前请求所在域名进行了动态处理。

yii2动态access-control-allow-origin

查看 yii2 的\yii\filters\cors类源码,如下:

class cors extends actionfilter{  /**   * @var array cors所用的响应头   */  public $cors = [    'origin' => ['*'],    'access-control-request-method' => ['get', 'post', 'put', 'patch', 'delete', 'head', 'options'],    'access-control-request-headers' => ['*'],    'access-control-allow-credentials' => null,    'access-control-max-age' => 86400,    'access-control-expo-headers' => [],  ];    /**   * 执行action前要做的事   * @inheritdoc   */  public function beforeaction($action)  {    $this->request = $this->request ?: yii::$app->getrequest();    $this->respon = $this->respon ?: yii::$app->getrespon();    ... ...    $requestcorsheaders = $this->extractheaders();    //获取cors所用的响应头    $responcorsheaders = $this->prepareheaders($requestcorsheaders);    //设置cors所用的响应头    $this->addcorsheaders健身房设计方案($this->respon, $responcorsheaders);    return true;  }    /**   * 处理cors所用的响应头,动态处理access-control-allow-origin域  考研什么时候开始准备 * @param array $requestheaders cors headers we have detected   * @return array cors headers ready to be nt   */  public function prepareheaders($requestheaders)  {    $responheaders = [];    //$requestheaders['origin']为源地址,请求所在域名    if (ist($requestheaders['origin'], $this->cors['origin'])) {      //源地址在白名单中,则设置access-control-allow-origin为源地址      if (in_array('*', $this->cors['origin']) || in_array($requestheaders['origin'], $this->cors['origin'])) {        $responheaders['access-control-allow-origin'] = $requestheaders['origin'];      }    }    ... ...   }}

主要思想就是,查看源地址是否在 cors 白名单中,在则设置 access-control-allow-origin 域的值为源地址。这样就能满足 access-control-allow-origin 为一个值的限制,同时也能允许指定的域名进行 cors。

注意:使用该方法请确保 nginx 配置中未操作 access-control-allow-origin 域。

总结

通过 nginx 设置 access-control-allow-origin 进行 cors,有且只能有一个现在学什么技术有前途特定域名,局限性较大。通过代码逻辑操作 access-control-allow-origin 来实现 cors,则比较灵活,能解决多个域名进行 cors 的需求,但是如果接口异常,跨域设置则会失效。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持www.887551.com。

本文发布于:2023-04-06 16:39:02,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/4b4a5f2d975519e8b53054da8a70762d.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:Yii支持多域名cors原理的实现.doc

本文 PDF 下载地址:Yii支持多域名cors原理的实现.pdf

标签:域名   多个   源地址   名单
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图