為什么發送OPTIONS請求
- 獲取服務器支持的HTTP請求方法;
- 用來檢查服務器的性能。例如:AJAX進行跨域請求時的預檢,需要向另外一個域名的資源發送一個HTTP OPTIONS請求頭,用以判斷實際發送的請求是否安全。
如何處理OPTIONS請求
經典解決方法
一般而言,只需要加入以下三行代碼即可解決
//指定允許其他域名訪問
header('Access-Control-Allow-Origin:*');
//響應類型
header('Access-Control-Allow-Methods:*');
//響應頭設置
header('Access-Control-Allow-Headers:x-requested-with,content-type');
但是這個方法在thinkphp框架中使用時,如果有多個控制器,或控制器下的方法比較多,又不能明確確定哪些需要跨域哪些不需要的情況下,逐個方法添加這三行代碼,顯得非常僵硬。
更優雅的方法
在./application/index/tags.php
中找到app_init,並注冊解決跨域的類
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
// 應用行為擴展定義文件
return [
// 應用初始化
'app_init' => ['app\index\behavior\CORS'],
// 應用開始
'app_begin' => [],
// 模塊初始化
'module_init' => [],
// 操作開始執行
'action_begin' => [],
// 視圖內容過濾
'view_filter' => [],
// 日志寫入
'log_write' => [],
// 應用結束
'app_end' => [],
];
在./application/index/behavior/
中新建一個cors.php,將我們要攔截並添加的三行代碼放上去
<?php
namespace app\index\behavior;
use think\Response;
class CORS
{
public function appInit(){
header('Access-Control-Allow-Origin:*');
header('Access-Control-Allow-Methods:*');
header('Access-Control-Allow-Headers:x-requested-with,content-type');
}
}
使用postman測試,發現有如下三行headers即為成功。
跨域問題解決的原理
觀察上面的三行代碼可以發現,只需要在response中加入這三個header就可以了。一般情況下,只要有合適的認證機制(如token)就可以有效防止CSRF攻擊,因此可以直接設置一個全局的跨域。