zoukankan      html  css  js  c++  java
  • php 跨域问题

    /**
     * 跨域请求设置
     */
    function checkAllowOrigin()
    {
        //从配置文件获取允许源域名
        $allowOrigin = explode(',', env('app.allow_origin'));
        if (in_array('*', $allowOrigin)) {
            $origin = '*';
            $allow = true;
        } else {
            $origin = request()->header('Origin') ?? request()->domain();
            $allow = in_array($origin, $allowOrigin);
        }
    
        if (!$allow) {
            exit('403');
        }
    
        //允许跨域的来源域名
        header('Access-Control-Allow-Origin:'.$origin); 
        header('Access-Control-Allow-Methods: GET, POST, OPTIONS');//允许跨域的请求方法
        // 带 cookie 的跨域访问
        header('Access-Control-Allow-Credentials: true');
        // 响应头设置(允许跨域的头部)
        header('Access-Control-Allow-Headers:x-requested-with,Content-Type,X-CSRF-Token,Access-Token');
    }

    四点:

     1.允许跨域的来源域名

     2.允许跨域的请求方法

     3.允许带 cookie 的跨域访问(不允许改为false)

       4.允许跨域的头部(记得把自定义的header头也写进去,不然跨域会不成功)

    特别要注意的是3和4点。比如第4点的Access-Token,我们项目自定义的,忘了加。在有用户登陆的时候,就一直无法跨域。

    踩坑记

    前端(A域名)vue,axios访问本地(C域名)接口,没问题;访问线上接口(B域名),总报一下错误:

    Access to XMLHttpRequest at 'http:/B.cn/teacher/auth/nearTeacherfrom origin 'http://A.coom' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

    而访问 http:/B.cn/api/XXX 接口,这么都没有问题。

    自己写个简单vue请求线上接口,没问题

    <script>
    new Vue({
      el: '#app',
      data () {
        return {
          info: null
        }
      },
      mounted () {
        axios.defaults.withCredentials = true;
        axios
          .post('http://B.cn/teacher/auth/nearTeacher')
          .then(response => (this.info = response))

      
        axios({
            method: 'post', 
            url: 'http://alone.seeonce.me/teacher/auth/nearTeacher',  
            withCredentials: true
         })
    
      }
    })
    </script>

    反复确认线上跨域有设置    header('Access-Control-Allow-Credentials: true');

    反复确认线上代码配置和本地一样,线上缓存清除,问题都还是如此。

    点开谷歌浏览器查看NetWork-》other,可以看到OPTIONS请求204,但肯定有问题

    在代码里把跨域的代码都搬到index.php里面了,结果发现还是问题如此

    此刻我觉得应该是nginx配置问题:

    结果发现:本地nginx配置没有配置跨域,而线上有,但是线上漏了个add_header 'Access-Control-Allow-Credentials' 'true';

          

      location / {
    
      if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' "$http_origin";
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Access-Token,Content-Range,Range';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Max-Age' 7200;
        add_header 'Content-Type' 'text/json; charset=utf-8';
        add_header 'Content-Length' 0;
        return 204;
      }
    
     }

    所以OPTION的时候才会一直返回204,拦截住了

     结论:

    1.访问thinkphp的api模块不走OPTION或者前端vue没有设置 withCredentials = true

    2.自己写的vue,具备withCredentials = true(测试过,php代码关掉就会出错),但是nignx配置控制不到。可能没走OPTIONS。

    3.nignx配置没配置到这的问题,加上问题就都解决了。nignx只控OPTIONS这关,真实请求POST还需要php代码在控制一次。

  • 相关阅读:
    图像处理之优化---任意半径局部直方图类算法在PC中快速实现的框架
    新的验证方式---短信验证和语言验证
    习武 之路---通背拳和苗刀!
    模式识别之Shape Context---利用Shape Context进行形状识别
    ELK 部署
    rsync实现文件备份同步
    oracle-3-子查询和常用函数
    oracle-2中commit 详解
    使用nginx绑定域名,代理gitlab
    Linux Crontab 安装使用详细说明
  • 原文地址:https://www.cnblogs.com/hfdp/p/14654952.html
Copyright © 2011-2022 走看看