關於Laravel下Cors跨域POST請求的一種實現方法

以前作了一個公司的內部管理系統,如今但願經過在釘釘上開發一個小應用查看相關數據,在此過程當中涉及了HTTP的跨域請求的問題,在瞭解相關信息後,打算基於CORS實現。關於CORS(跨域資源共享),見這篇文章
CORS中,對於簡單請求,只需在服務器進行相關的字段驗證後進行響應便可,主要是驗證請求的來源及請求的方法等是不是服務器許可的。
而對於複雜請求,則瀏覽器會先發送一個options請求到服務器進行驗證,驗證經過後,再發送用戶的請求。再options請求中,服務器會返回容許的請求源、請求方法及頭部字段等。php

對於CORS在Laravel中的實現須要在項目中加入一箇中間件Cors,html

<?php

namespace App\Http\Middleware;

use Closure;

class Cors
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        

        header("Access-Control-Allow-Origin: *");

        $headers = [
            'Access-Control-Allow-Methods'=> 'POST, GET, OPTIONS, PUT, DELETE',
            'Access-Control-Allow-Headers'=> 'Content-Type, X-Auth-Token, Origin'
        ];

        $response = $next($request);
        foreach($headers as $key => $value) 
            $response->header($key, $value);
        return $response;
    }
}

對於簡單請求,好比get請求,在路由中加入該中間件便可。
但對於複雜請求,則處理不了。(根據文檔,POST請求知足某些條件是纔是複雜請求,但不知道爲什麼,我發出的POST請求都是複雜請求,即瀏覽器首先會觸發一次options請求,再提交客戶的實際請求)。
對於只是採起與簡單請求相同的方法,則對於複雜請求沒法正確響應。跨域

如下是GET請求的請求-響應信息:
圖片描述瀏覽器

如下是POST請求的響應:
圖片描述服務器

可見POST請求中,瀏覽器先進行了OPTIONS請求,但該請求的響應中,並無GET響應中的cors

Access-Control-Allow-Headers:Content-Type, X-Auth-Token, Origin
Access-Control-Allow-Methods:POST, GET, OPTIONS, PUT, DELETE
Access-Control-Allow-Origin:*

等跨域控制字段。學習

經過查詢資料,Laravel對於OPTIONS請求會自動常規響應200。因此缺乏必要的頭部信息。
因此,我經過在路由中專門加入一個處理options的路由spa

Route::options('cors/test',function(){
    return response('ok')
                         ->header('Access-Control-Allow-Methods','POST, GET, OPTIONS, PUT, DELETE')
                         ->header('Access-Control-Allow-Headers','Content-Type, X-Auth-Token, Origin');
})->middleware('cors');

即保證了OPTIONS響應了必要的頭部信息。
但該方法須要關閉Laravel中相應路由的CSRF功能,具體在AppHttpMiddlewareVerifyCsrfToken添加code

protected $except = [
        'cors/*'
    ];

雖然解決了問題,但對於其中的不少細節仍是不瞭解,須要進一步學習。htm

相關文章
相關標籤/搜索