一萌焰、什么是CORS
CORS(Cross-Origin Resource Sharing 跨源資源共享)颤霎,當(dāng)一個(gè)請(qǐng)求url的協(xié)議猪钮、域名、端口三者之間任意一與當(dāng)前頁(yè)面地址不同即為跨域述雾。
二街州、問題描述
本人最近在寫商城的CMS 系統(tǒng)時(shí),CMS訪問API 就要到了跨域問題:
- 跨域點(diǎn):
CMS 頁(yè)面是通過http協(xié)議訪問的玻孟,而CMS要訪問的接口卻在https上唆缴,
url 協(xié)議不同,導(dǎo)致跨域黍翎。而且還報(bào)了了一個(gè)訪問接口的404錯(cuò)誤面徽,
后來(lái)查了一下,當(dāng)瀏覽器檢查到有跨域的問題匣掸,會(huì)對(duì)訪問的接口做一個(gè)判斷斗忌,如果是簡(jiǎn)單的接口质礼,則直接訪問,如果是復(fù)雜的接口织阳,則需要先發(fā)送一個(gè)option請(qǐng)求,但是我的路由里面沒有定義該接口的option請(qǐng)求 砰粹,因此報(bào)了一個(gè)404錯(cuò)誤
- 規(guī)避
后來(lái)我想唧躲,我的CMS和API都是在同一域名下,不應(yīng)該存在協(xié)議不同問題碱璃,后來(lái)我又重新用https協(xié)議訪問了一下CMS弄痹。果然問題就解決了。
三嵌器、由跨域引起的思考
雖然我現(xiàn)在這個(gè)跨域的問題解決了肛真,但是如果后續(xù)CMS 和API做分離,還是會(huì)遇到跨域問題爽航,所以這個(gè)問題必須解決蚓让。其實(shí)大多數(shù)跨域問題,只要在訪問的接口中寫入下面的一段話就可以解決:
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");
header('Access-Control-Allow-Methods: GET,POST');
但是正如上面所說(shuō)讥珍,有些瀏覽器在檢查到跨域問題時(shí)历极,會(huì)有兩次請(qǐng)求,第一次是option衷佃,如果放回200趟卸,然后才會(huì)正式去訪問接口。所以需要在有跨域的地方氏义,都加上一個(gè)對(duì)option請(qǐng)求的處理锄列,但是如果項(xiàng)目的接口太多,在每個(gè)接口都加這樣一個(gè)判斷惯悠,顯然有點(diǎn)費(fèi)時(shí)費(fèi)力邻邮,此時(shí),AOP思想又再次登場(chǎng)了吮螺。
四饶囚、利用AOP思想,結(jié)合CORS,解決跨域問題
我目前做的微信商城項(xiàng)目是基于thinkPHP5鸠补,thinkPHP5對(duì)AOP有較好的支持萝风,所謂的AOP 就是面向切面編程的思想。
在thinkPHP的application目錄下紫岩,有一個(gè)tags.php文件规惰,這個(gè)能保證加載全局的函數(shù)。
4.1
如下圖所示泉蝌,將CORS跨域處理文件的路徑定義到app_init下歇万,這就能保證揩晴,tp5框架在初始化就加載這個(gè)跨域處理函數(shù)
4.2
在application/api下新建一個(gè)behavior文件,并新建一CORS.php跨域處理文件
具體代碼如下:
namespace app\api\behavior;
class CORS
{
//對(duì)應(yīng)tags.php的app_init 使用駝峰命名贪磺,不能修改方法名
public function appInit(&$params)
{
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Headers: token,Origin, X-Requested-With, Content-Type, Accept");
header('Access-Control-Allow-Methods: POST,GET');
if(request()->isOptions()){
exit();
}
}
}
五硫兰、驗(yàn)證
為了構(gòu)造跨域,我的cms 還是用http格式訪問寒锚,對(duì)應(yīng)的https的api接口
驗(yàn)證成功劫映,在瀏覽器判斷有跨域問題,首先會(huì)發(fā)起一個(gè)options請(qǐng)求刹前,在options請(qǐng)求被tp處理并返回200后泳赋,才開始正式訪問數(shù)據(jù)。并成功請(qǐng)求到數(shù)據(jù)喇喉。