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代码在控制一次。

  • 相关阅读:
    从上往下打印二叉树
    栈的压入、弹出序列
    连续子数组的最大和
    链表中环形的入口
    1月项目痛点
    problem:vue组件局部刷新,在组件销毁(destroyed)时取消刷新无效问题
    重点:浏览器的工作原理
    12月中旬项目中出现的几个bug解决方法的思考
    12月中项目问题复盘之对项目进度把控的反思
    problem: vue之数组元素中的数组类型值数据改变却无法在子组件视图更新问题
  • 原文地址:https://www.cnblogs.com/hfdp/p/14654952.html
Copyright © 2011-2022 走看看