原創:【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簡單請求】驗證中間件(如果是簡單請求,上面都可以省略),App\Middleware\AjaxHeader.php,kernel.php注冊在api里面

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\{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的復雜請求。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM