thinkphp5 關於跨域的一些坑,附上解決辦法(比較全面了)
專案背景:前端是uniapp開發的h5,後端是tp5,其他語言我覺得應該大同小異,主要是思路,本文就以這倆為例吧
1、首先在tp5的入口檔案:public/index.php 在裡面新增三行:
// [ 應用入口檔案 ] header("Access-Control-Allow-Origin:*"); header("Access-Control-Allow-Methods:GET, POST, OPTIONS, DELETE"); header("Access-Control-Allow-Headers:x-requested-with, Referer,content-type,token,DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type, Accept-Language, Origin, Accept-Encoding"); // 不用多說,就是上面三行,注意第三行,裡面有一個引數:token,這個是為後面自定義header頭準備的<br> // 定義應用目錄 define('APP_PATH', __DIR__ . '/../application/'); // 載入框架引導檔案 require __DIR__ . '/../thinkphp/start.php';
這樣就可以了,在tp5的方面就弄完了,沒錯,就是這麼簡單而且一般百度能搜尋到的,就是這些
一般情況下這樣也就行了,但是有的時候還會存在跨域,原因就是前端請求的時候有一個地方需要注意
2、前端uniapp的網路請求用的是uni.request,不管是uni.request還是jq的ajax,都一樣,都需要注意一點,就是請求型別不能是application/json!!
uni.request({ url: 'http://test-tp5.io', data: {a:1,b:2}, header: { 'content-type': 'application/x-www-form-urlencoded', // 用這個! // 'content-type': 'application/json', 這裡是反面舉例,一定不要用這個!不信你試試! 'token': 'this is token' // 看到這個token了沒有,它在在第一步的第三行出現過~ }, method: 'POST', success: (res)=> { console.log('成功了:',res); }, fail: (res)=>{ console.log('出錯了:',res); } });
header中所有自定義的引數,都要寫在第一步中的第三行裡面,要不然就等著跨域吧~
OK,到這絕大部分到這也就沒有問題了但是!鄙人就是這麼的與眾不同!沒錯,當我弄到這的時候!我又跨域了!想哭了
一開始我的開發環境是phpstudy,在到這一步的時候,跨域問題已經消失的無影無蹤了,然後前幾天我換成了docker,然後久違的跨越又來了。。。
而且跨域的原因是自定義header引數,即如果我把request裡面的token引數去掉,請求是正常的,加上就不行了!
此時經過對比我發現,phpstudy我用的是apache,docker我用的是nginx,而且當我把專案遷到phpstudy的時候就沒有跨域問題,此時問題原因顯而易見!
3、經過搜尋、測試,現得出在nginx下如何配置跨域的自定義header引數
在站點配置檔案中 location / {} 裡面新增下面幾行:
location / {
if ($request_method = 'OPTIONS') {
# 【必須】建議在釋出環境用域名而不是“星”號
add_header Access-Control-Allow-Origin '*';
# Allow-Headers 指定允許的自定義請求頭,如使用者 Token,而且這些不用寫那麼多,只寫自定義的引數就可以
add_header Access-Control-Allow-Headers 'token';
# 一般來說在 POST 請求時因為 Content-Type 的原因在本次 OPTIONS 預請求後,
# 會再發送的 POST 請求,而 POST 請求是可以正常接收的
# add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, PATCH, OPTIONS';
# 請求是否攜帶 Cookie,無需要可忽略。有說該設定為 true 時 Allow-Origin 不可為 '*'
# add_header Access-Control-Allow-Credentials true;
# 這個響應 Content-Type 也是根據需要設定(一般情況可以不用設定)
# add_header Content-Type 'application/json; charset=utf-8';
# 如下 Content-Length 可忽略,返回狀態碼根據個人習慣可設定為 200
add_header Content-Length 0;
return 204;
}
# 沒錯,為了方便你們對比,上面這些才是要新增的
# 而且你們可能發現了,我上面有好多註釋掉的,因為這些是我在搜尋出來的,而且經過我一步步的註釋,發現只要一開始的兩行和最下面的兩行就可以了
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php?s=/$1 last;
break;
}
}
至此才是真正的解決了跨域的問題,可能是apache預設配置了的原因,apache不用配置這第三步
4、為啥還有第4步???
這第4步算是一個小提醒吧,就是tp程式不要報錯。。。因為當tp5丟擲異常的時候,會影響你public/index.php中的配置,導致產生跨域~
tip:不知道這篇文章還能不能回到首頁,哈哈~~