且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

错误页面不遵循内容类型/格式

更新时间:2023-11-19 14:01:58

我刚刚遇到了同样的问题,虽然你的问题已经很老了,而且 symfony 从那时起又升级了几个版本,但问题仍然相关,所以即使你不需要再知道了,也许其他人会知道.

I just hit the same problem, and although your question is quite old and symfony bumped a few versions up since then, the problem is still relevant, so even if you don't need to know it any more, maybe somebody else will.

您最初的问题可能是由此处描述的错误引起的,但没有在最初的帖子之后发生了很多事情.从那以后整个代码库都被更新了,所以虽然同样的症状再次出现,但错误并不相关.我在这里发布它是因为现在任何寻找答案的人都可能会发现这个问题(就像我所做的那样:).

Your original problem was probaly caused by error described here, but there wasn't much going on about it after initial post. Since then the entire codebase was updated, so while the same symptoms reappeared, the error is not related. I am posting it here because anybody looking for an answer these days will probably find this question (as I did :).

即使直接从内核异常处理器返回JsonResponse,它仍然会有Content-Type: text/html;字符集=UTF-8.这让我很难过,以至于我使用 netcat 发出手动请求,中间没有任何智能软件,结果在这种情况下,响应实际上有两个不同的 Content-Type 标头:

Even when returing JsonResponse directly form kernel exception handler, it will still have Content-Type: text/html; charset=UTF-8. This stumped me so much that I used netcat to make a manual request without any smart software in between, and it turns out that the response in such case has actually two different Content-Type headers:

HTTP/1.0 500 Internal Server Error
Connection: close
X-Powered-By: PHP/5.5.9-1ubuntu4.17
Content-Type: text/html; charset=UTF-8
Cache-Control: private, must-revalidate
Content-Type: application/json
pragma: no-cache
expires: -1
X-Debug-Token: 775c55
X-Debug-Token-Link: http://127.0.0.1:8000/_profiler/775c55
Date: Thu, 27 Oct 2016 23:08:31 GMT

现在,双 Content-Type 标头不是您每天都能看到的.似乎这是在仅用于调试模式的 Symfony\Component\Debug\ExceptionHandler 类中实现的.为了尽可能健壮,它首先呈现描述抛出异常的标准 Symfony 错误页面.渲染的内容不会直接发回,而是利用 PHP 的输出缓冲功能来缓冲和存储生成的输出.然后它尝试从框架生成自定义错误页面.如果失败,则发送先前准备好的消息.

Now, double Content-Type header is not something you see everyday. It seems that this is implemented in Symfony\Component\Debug\ExceptionHandler class that is only used in debug mode. In order to be as robust as possible, it first renders standard Symfony error page that describes thrown exception. Rendered content is not sent back directly, instead it leverages PHP's output buffering feature to buffer and store produced output. Then it attempts to produce custom error page from framework. In case this fails, previously prepared message is sent.

然而,输出缓冲仅适用于消息内容,而不适用于标头 - 这些始终直接发送.这个问题只出现在调试环境中,错误的异常内容类型只在 WebAPI 中常见,其中调试模式可以说几乎没有用.这使得暴露面相对较小,但如果需要测试同时提供 WebAPI 和最终用户界面的应用程序,这可能会成为一个问题.

Output buffering however works only for message content, and not for headers - these are always sent directly. This problem only appears in debug environment, and unusual content types on error are only common in WebAPI, where debug mode is arguably of little use. This makes exposure surface relatively small, but if an application that offers both WebAPI and end-user interface needs to be tested, this might become a problem.

在不修改内部 Symfony 文件的情况下解决这个问题似乎是不可能的.输出控制位于 symfony 内核深处,不提供任何配置.无论如何,我不相信这种解决方案的好处.如果有人可以向我解释在自定义异常处理程序期间可能发生的事情,如果失败,默认处理程序将无用?也许用户代码弄乱了 ob_* 函数?

Solving this problem without modifying internal Symfony files doesn't seem possible. Output control sits deep within symfony kernel and doesn't offer any configuration. Anyway, I am not convinced of benefits of such solution. If anyone could explain to me what could have happened during custom exception handler that would make default handler useless in case it failed? Maybe user code messing with ob_* functions?