php跨域请求解决方案_swoft2 -跨域与中间件详解
一、什么是跨域?
同源策略是一種約定,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,瀏覽器很容易受到XSS、CSRF等攻擊。所謂同源是指”協(xié)議+域名+端口”三者相同,即便兩個不同的域名指向同一個ip地址,也非同源。
同源策略限制內(nèi)容有:
Cookie、LocalStorage、IndexedDB 等存儲性內(nèi)容
DOM 節(jié)點
AJAX 請求發(fā)送后,結(jié)果被瀏覽器攔截了
但是有三個標簽是允許跨域加載資源:
<img src=XXX> <link href=XXX> <script src=XXX>因為現(xiàn)在大多數(shù)項目采用前后分離的開發(fā)模式,所以前后端交互經(jīng)常遇到跨域的情況.在 swoft2 配置跨域是通過中間件來完成的.下面我們教大家怎么配置.中間件簡單介紹
可以看到中間件是貫穿整個請求的,請求開始之后會:匹配路由->執(zhí)行中間件->執(zhí)行控制器方法->再次執(zhí)行中間件。可以當作其他框架的前置方法和后置方法,中間件在調(diào)用控制器方法之前會執(zhí)行,調(diào)用之后也還會執(zhí)行。
中間件起到的作用
中間件在可以進行用戶登陸的驗證、權(quán)限校驗、數(shù)據(jù)修正、統(tǒng)一返回格式等等,其實只要了解了生命周期之后基本上就可以想象到中間件的作用。
定義中間件
只需要實現(xiàn)了 SwoftHttpServerContractMiddlewareInterface 接口均為一個合法的中間件,其中 process() 方法為該中間件邏輯處理方法。不過我們通常把代碼放在 app/Http/Middleware
配置全局中間件
添加全局中間件,所有控制器都會走這里的中間件,在做
添加多個中間件
修改文件 app/bean.php'httpDispatcher' => [// Add global http middleware'middlewares' => [AppHttpMiddlewareFavIconMiddleware::class,SwoftHttpSessionSessionMiddleware::class,AppHttpMiddlewareControllerMiddleware::class,//我們自己的中間件SwoftViewMiddlewareViewMiddleware::class,],'afterMiddlewares' => [SwoftHttpServerMiddlewareValidatorMiddleware::class]],配置局部的中間件
通過 @Middleware 和 @Middlewares, 可以很方便的配置中間件到當前的 Controller 和 Action 內(nèi)
當將此注解應(yīng)用于 Controller 上,則作用域為整個 Controller將此注解應(yīng)用于 Action 上,則作用域僅為當前的 Action@Middleware 用于配置單個中間件
/*** Class HomeController* @Controller()* @Middleware(ControllerMiddleware::class)* })*/class HomeController{....}@Middlewares 顯而易見的是用于配置一組 @Middleware,按照定義順序依次執(zhí)行
/*** Class HomeController* @Controller()* @Middlewares({@Middleware(SessionMiddleware::class),* @Middleware(ControllerMiddleware::class),* })*/ class HomeController {.... }跨域中間件簡單示例
文件 App/Http/Middlewar/ControllerMiddleware.php<?php declare(strict_types=1); namespace AppHttpMiddleware; use PsrHttpMessageResponseInterface; use PsrHttpMessageServerRequestInterface; use PsrHttpServerRequestHandlerInterface; use SwoftBeanAnnotationMappingBean; use SwoftHttpMessageContentType; use SwoftHttpServerContractMiddlewareInterface; use SwoftHttpSessionHttpSession;/*** @Bean()*/ class ControllerMiddleware implements MiddlewareInterface {/*** Process an incoming server request.** @param ServerRequestInterface $request* @param RequestHandlerInterface $handler** @return ResponseInterface* @inheritdoc*/public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface{$sess = HttpSession::current();$sess->set('__SWOFT_SESSION_ID__', 'SWOFT_SESSION_ID');//修復(fù)sessoion bugif ('OPTIONS' === $request->getMethod()) {$response = Context::mustGet()->getResponse();return $this->configResponse($response);}$ret = $handler->handle($request);$data=$ret->getData();if(is_object($data)||is_array($data)){return $this->configResponse(response(ContentType::JSON)->withData($data));}return $this->configResponse(response(ContentType::HTML)->withContent($data));}private function configResponse(ResponseInterface $response){return $response->withHeader('Access-Control-Allow-Origin', '*')->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization')->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS');} }注入中間件
將中間件注入全局讓每個請求都能生效,并且這個中間件應(yīng)該在其他中間件之前執(zhí)行,所以放入 preMiddlewares 'httpDispatcher' => [// Add pre http middleware"preMiddlewares"=>[AppHttpMiddlewareFavIconMiddleware::class,SwoftHttpSessionSessionMiddleware::class,AppHttpMiddlewareControllerMiddleware::class,],'middlewares' => [// SwoftWhoopsWhoopsMiddleware::class,// Allow use @View tagSwoftViewMiddlewareViewMiddleware::class,],'afterMiddlewares' => [SwoftHttpServerMiddlewareValidatorMiddleware::class]],重要
上面雖然把中間件配置好了,但是還是不能跨域訪問,因為請求默認是只允許get和post請求,而跨域會發(fā)送option請求,所以這個地方是個坑,很多跨域配置不成功就是因為這個原因。所以需要設(shè)置 RequestMapping 的注解,并且設(shè)置 method 參數(shù)允許 OPTIONS 請求,這樣就能實現(xiàn)跨域 /*** @RequestMapping(route="/prolist" ,method={RequestMethod::POST,RequestMethod::OPTIONS})*/public function prod_list(){return [data=>"跨域設(shè)置成功"];}以上內(nèi)容希望幫助到大家,很多PHPer在進階的時候總會遇到一些問題和瓶頸,業(yè)務(wù)代碼寫多了沒有方向感,不知道該從那里入手去提升,對此我整理了一些資料,包括但不限于:分布式架構(gòu)、高可擴展、高性能、高并發(fā)、服務(wù)器性能調(diào)優(yōu)、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql優(yōu)化、shell腳本、Docker、微服務(wù)、Nginx等多個知識點高級進階干貨需要的可以免費分享給大家,需要
PHP進階架構(gòu)師>>>視頻、面試文檔免費獲取?shimo.im或 者關(guān)注咱們下面的知乎專欄
PHP架構(gòu)師圈子?zhuanlan.zhihu.com總結(jié)
以上是生活随笔為你收集整理的php跨域请求解决方案_swoft2 -跨域与中间件详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: net 控制台 定时_.NET Core
- 下一篇: enfp工具箱怎么用_隐喻:你的工具箱