• 原创:【ajax | axios跨域简单请求+复杂请求】自定义header头Token请求Laravel5后台【亲测可用】


    如标题:我想在ajax的header头增加自定义Token进行跨域api认证并调用,api使用laravel5编写,如何实现?

    首先,了解下CORS简单请求和复杂请求。

         -- CORS简单请求 --

    链接:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS

    1、ajax跨域,使用CORS方式  --  (ajax跨域会自动提交origin字段,用户不可伪造)

    2、HTML的js:

    </body>
    <script type="text/javascript">
        $(function(){
            $(document).on("click", ".btn-all2", function(){
                $.ajax({
                    url:"http://t-local.*****.com/wechat/auth/up?call_back=http%3A%2F%2Ftest.*****.com%2Findex.php%3Fg%3DWeixin%26m%3DWeixin%26a%3Dindex",
                    dataType:"json",
                    type:"get", //origin字段不允许自定义伪造;跨域请求浏览器自动带上origin
    
                    // 允许携带cookie凭证
                    xhrFields: { withCredentials: true },
                    // 允许跨域
                    crossDomain: true,
    
                    success:function(data){
                        console.log('success');
                        console.log(JSON.stringify(data));
                    },
                    error: function(data){
                        console.log('error');
                        console.log(JSON.stringify(data));
                    }
                })
            })
        })
    </script>
    </html>

    laravel5后台ajax请求过滤中间件: -- laravel 5 用来处理【简单请求】或者【复杂请求的第二次请求】

    //跨域XML请求,会自动带上http_origin字段
    public function handle( $request, Closure $next )
        {
            $origin = isset($_SERVER['HTTP_ORIGIN'])? $_SERVER['HTTP_ORIGIN'] : '';
            $allow_origin = Config::get('app.allow_origin');
            $allow_origin_dynamic = Config::get('app.allow_origin_dynamic');
    
    
            $allowOrigin = false;
            if ( in_array( $origin, $allow_origin ))
            {
                $allowOrigin = true;
            } else {
                foreach ( $allow_origin_dynamic as $item )
                {
                    if ( strpos( $origin, $item ) !== false )
                    {
                        $allowOrigin = true;
                        break;
                    }
                }
            }
            if ( $allowOrigin )
            {
                header('Access-Control-Allow-Origin: '.$origin);
                header('Access-Control-Allow-Methods:POST,GET,OPTIONS,PUT,DELETE');
                header('Access-Control-Allow-Headers:x-requested-with,content-type');
                header('Access-Control-Allow-Credentials:true');
            }
            return $next($request);
    
        }

        ------  CORS复杂请求   --------

    链接:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS

    复杂请求 =【预请求 + 简单请求】;

    一次XMLHttpRequest会发送两次请求,一次options、一次自定义的请求

    那么在TP5中,我们可以使用行为扩展处理ajax|axios 带自定义头token的CORS请求,在laravel5中怎样解决呢?

    laravel5 解决方案:

    1、域名一:local.domian.com前端发起跨域ajax请求:访问laravel5的t-local.domian.com域名二

    <script type="text/javascript">
        $(function(){
            $(document).on("click", ".btn-all2", function(){
                $.ajax({
                    url:"http://t-local.****.com/api/wechat/auth/up?call_back=http%3A%2F%2Ftest.****.com%2Findex.php%3Fg%3DWeixin%26m%3DWeixin%26a%3Dindex",
                    dataType:"json",
                    type:"get", 
    
                    //origin字段不允许自定义伪造;跨域请求浏览器自动带上origin
    
    
                    //自定义请求头认证token
                    headers: { 'token' : "2211zxz" },
    
                    // 允许携带cookie凭证
                    xhrFields: { withCredentials: true },
                    // 允许跨域
                    crossDomain: true,
    
                    success:function(data){
                        console.log('success');
                        console.log(JSON.stringify(data));
                    },
                    error: function(data){
                        console.log('error');
                        console.log(JSON.stringify(data));
                    }
                })
            })
        })
    </script>

    2、在laravel的route/api.php路由文件,增加以下路由规则:

    /**
    * laravel5发送复杂cors请求,类似jwt、自定义请求头token等,会先发送预请求options
    * @param : 预请求options的【Access-Control-Allow-Origin:】绝对不可以设置成*,否则报错
    * @return : code 200
    * date: 2019年10月30日下午2:29:50
    * author: xzz
    */
    Route::options('/{all}',function () {
        //file_put_contents(storage_path('logs/SERVER_Header.txt'), 'array = ' . var_export(request()->header(), true) . PHP_EOL, FILE_APPEND);
        //file_put_contents(storage_path('logs/SERVER_Header.txt'), 'string' . var_export(request()->header('ORIGIN'), true) . PHP_EOL, FILE_APPEND);
        $origin = request()->header('ORIGIN')??request()->header('HTTP_ORIGIN');
        
        header("Access-Control-Allow-Origin: $origin");
        header("Access-Control-Allow-Credentials: true");
        header('Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE');
        header('Access-Control-Allow-Headers: Origin, Access-Control-Request-Headers, SERVER_NAME, Access-Control-Allow-Headers, cache-control, token, X-Requested-With, Content-Type, Accept, Connection, User-Agent');
    })->where(['all' => '([a-zA-Z0-9-]|/)*']);

    3、返回前端F12打开,发现options请求已通过:

    4、在创建一个【ajax简单请求】验证中间件(如果是简单请求,上面都可以省略),AppMiddlewareAjaxHeader.php,kernel.php注册在api里面

    <?php
    
    namespace AppHttpMiddleware;
    
    use Closure;
    use IlluminateSupportFacades{Config};
    
    class AjaxHeader
    {
        /**
         * @param $request
         * @param Closure $next
         * @return mixed
         */
        public function handle( $request, Closure $next )
        {
            file_put_contents(storage_path('logs/1.txt'), var_export($_SERVER, true) . PHP_EOL, FILE_APPEND);
            file_put_contents(storage_path('logs/SERVER_HeaderReal.txt'), 'array = ' . var_export(request()->header(), true) . PHP_EOL, FILE_APPEND);
            file_put_contents(storage_path('logs/SERVER_HeaderReal.txt'), 'string' . var_export(request()->header('ORIGIN'), true) . PHP_EOL, FILE_APPEND);
            
            $origin = isset($_SERVER['HTTP_ORIGIN'])? $_SERVER['HTTP_ORIGIN'] : '';
            $allow_origin = Config::get('app.allow_origin');
            $allow_origin_dynamic = Config::get('app.allow_origin_dynamic');
    
    
            $allowOrigin = false;
            if ( in_array( $origin, $allow_origin ))
            {
                $allowOrigin = true;
            } else {
                foreach ( $allow_origin_dynamic as $item )
                {
                    if ( strpos( $origin, $item ) !== false )
                    {
                        $allowOrigin = true;
                        break;
                    }
                }
            }
            if ( $allowOrigin )
            {
                header('Access-Control-Allow-Origin: '.$origin);
                header('Access-Control-Allow-Methods:POST,GET,OPTIONS,PUT,DELETE');
                header('Access-Control-Allow-Headers:x-requested-with,content-type,token');
                header('Access-Control-Allow-Credentials:true');
            }
            return $next($request);
    /*        return $next($request)-> header('Access-Control-Allow-Origin', '*')
            -> header('Access-Control-Allow-Methods', 'POST,GET,OPTIONS,PUT,DELETE')
            -> header('Access-Control-Allow-Headers', 'Content-Type,Accept,Authorization,X-Requested-With');*/
        }
    }

    5、上面注册的api中间件绑定到t-local的api/wechat/xxx路由上,从local域名发起访问t-local域名,发现get请求也成功返回了json数据

    返回的json数据:数据正确返回了,至于返回的是什么,这已经不重要了,不是吗?!!

    6、至此,则完成了laravel5 处理ajax 携带自定义header头Token,并发起的跨域CORS的复杂请求。

  • 相关阅读:
    linux环境变量
    linux make configure make
    摘自(http://www.ruanyifeng.com/blog/2011/07/linux_load_average_explained.html)
    linux eaccelerator
    linux du df ls
    linux phpize
    mysql 分页
    mysql 执行计划和慢日志记录
    mysql 添加/删除列(column)
    mysql 索引
  • 原文地址:https://www.cnblogs.com/xuzhengzong/p/11763337.html
Copyright © 2020-2023  润新知