【php】Swoft中间件跨域问题
Swoft中间件跨域问题
马尔科夫尼可夫发布于 2020-12-08
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种.
phpswooleswoft
阅读 207发布于 2020-12-08
本作品系原创,采用《署名-非商业性使用-禁止演绎 4.0 国际》许可协议
马尔科夫尼可夫
酷白发,小酒窝,主角标配的帅小伙~
7 声望
2 粉丝
马尔科夫尼可夫
酷白发,小酒窝,主角标配的帅小伙~
7 声望
2 粉丝
宣传栏
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种.
以上是 【php】Swoft中间件跨域问题 的全部内容, 来源链接: utcz.com/a/107243.html
得票时间