Swoft中间件跨域问题

码农天地 -
Swoft中间件跨域问题

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种.
特别申明:本文内容来源网络,版权归原作者所有,如有侵权请立即与我们联系(cy198701067573@163.com),我们将及时处理。

php介绍

PHP即“超文本预处理器”,是一种通用开源脚本语言。PHP是在服务器端执行的脚本语言,与C语言类似,是常用的网站编程语言。PHP独特的语法混合了C、Java、Perl以及 PHP 自创的语法。利于学习,使用广泛,主要适用于Web开发领域。

Tags 标签

phpswooleswoft

扩展阅读

加个好友,技术交流

1628738909466805.jpg