swoft2.0.x官网文档介绍的跨域解决demo如下:
这中形式在失常申请下看似没有问题,但如果$handler->handle($request)
步骤产生了异样,比方Validator拦挡到申请参数不非法,抛出了ValidatorException,那么后续增加申请头的操作就无奈失去执行.
那么,可不可以在执行handle办法前先通过Context::get()->getResponse()
取得Response对象,而后先对Response对象进行header设置呢?
答案是:NO,因为HttpContext没有提供response属性的setter,想要输入批改后的Response只能在框架提供的各个环节中return给调用者.
再看swoft源码Swoft\Http\Server\HttpDispatcher
:
不难发现:
1.`$requestHandler->handle($request)`这一步如果产生异样,那么咱们天然也得不到对应的`$response`.2.产生异样后,零碎会通过`$errDispatcher = Swoft::getSingleton(HttpErrorDispatcher::class)`失去错误处理的调度者,最初通过错误处理调度者返回一个Response
联合源码,最终的解决思路有4个:
1.在每个中间件执行$handler->handle($request)步骤时加上try/catch,捕捉执行中的异样,而后获取Response,设置好跨域后,失常return.2.利用swoft的HttpErrorDispatcher,在对应的异样解决类外面设置跨域的申请头(对于如何设置异样解决,请参见swoft官网文档).3.跳出在php中设置跨域申请header的思路,在比方nginx等代理服务器设置header.4.批改源码,在如下机会退出header设置,此处的$this->configResponse($response)办法为自定义的header设置办法:
以上4中办法:
前2中办法须要在注册的每一个中间件或者错误处理回调类外面增加header设置,比拟繁琐.最多是加个Common类来对立解决,但其它类依然须要继承这个Common类.第3种形式无需动php任何代码,举荐生产环境应用.然而在本地开发时须要Nginx等服务作为代理,略显繁琐.第4种形式,益处是只需动一处代码,就能作用全局.害处也很显著:动的那一处是框架提供的源码.倡议测试环境应用.
总结:
测试环境第4种,生产环境第3种.