我正在使用Apache来返回CORS响应来加速请求(之前我在应用程序代码中处理了这个问题,但这太慢了).在我的VirtualHost中,我有以下Apache代码:
SetEnvIfNoCase Access-Control-Request-Method "(GET|POST|PUT|DELETE|OPTIONS)" IsPreflight=1
SetEnvIfNoCase Origin "http(s)?://(myorigin.com)$" AccessControlAllowOrigin=$0$1
Header always set Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
Header always set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" env=IsPreflight
Header always set Access-Control-Allow-Headers "Content-Type, Authorization, Accept" env=IsPreflight
Header always set Access-Control-Max-Age "7200" env=IsPreflight
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteCond %{ENV:IsPreflight} 1
RewriteRule ^(.*)$ $1 [R=200,L]
Run Code Online (Sandbox Code Playgroud)
这实际上是非常好的.它检测请求是否是预检请求,如果是,则发送相应的标头.只有一个问题:预检请求返回200(所以浏览器发送正常请求),但正文是200 ERROR(哈哈):
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>200 OK</title>
</head><body>
<h1>OK</h1>
<p>The server encountered an internal error or
misconfiguration and was unable to complete
your request.</p>
<p>Please contact the server administrator at
you@example.com to inform them of the time this error occurred,
and the actions you performed just before this error.</p>
<p>More information about this error may be available
in the server error log.</p>
</body></html>
Run Code Online (Sandbox Code Playgroud)
虽然这可以正常工作,但我想从预检体中删除这个丑陋的错误,但我没有找到任何方法告诉Apache实际返回一个空体.
谢谢!
小智 16
对OPTIONS请求的204代码(无内容)的响应.
例如:
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=204,L]
Run Code Online (Sandbox Code Playgroud)
小智 11
对于CORS限制,204应该足够了.但是,在其他情况下,可能需要使用不同的状态代码进行空响应.
警告:ErrorDocument2xx和3xx是无证行为.
要发送空体的响应,请结合RewriteRule使用ErrorDocument.
# for 2xx, 4xx, 5xx, with or without flag [L]
RewriteRule ^ - [R=code,L]
# for 3xx
RewriteRule pattern substitution [R=code,L]
# for apache 2.4.13 and later
ErrorDocument code %{unescape:%00}
# for older versions,
# this can't be done without an empty file,
# the closest you can get using only the configuration is
ErrorDocument code " "
# if you're willing to use an empty file
ErrorDocument code /path/to/empty/file
Run Code Online (Sandbox Code Playgroud)
RewriteRule 使用204 No Content按预期工作,除了主要浏览器处理它与其他状态代码(例如200和301具有空内容)不同.
HTTP 204 No Content成功状态响应代码表示请求已成功,但客户端不需要离开其当前页面.
如果您访问URL并返回204,则Firefox和Chromium将表现为没有发生任何事情,导致栏中的页面和URL内容保持不变.
这可能是需要的或不是.
但是,如果您想要与具有空内容的200响应相同的效果并且关心Firefox/Chromium/etc,或者想要使用其他HTTP状态代码,那么RewriteRule使用204不是解决方案.
ErrorDocument我能找到返回空响应的最接近的方法是使用ErrorDocument返回自定义响应主体,并设置所需的主体内容.
尽管Apache的自定义错误响应文档指出:
可以为指定为错误条件的任何HTTP状态代码定义自定义错误响应 - 即任何4xx或5xx状态.
事实证明,可以通过ErrorDocument2xx和3xx状态代码指定自定义响应.
我们可以使用RewriteRule的[R]标志,进入这样的状态ErrorDocument才能生效.
但是,这不是故事的结尾,如下面的配置,
ErrorDocument 200 ""
Run Code Online (Sandbox Code Playgroud)
将引发此错误消息,
ErrorDocument takes two arguments, Change responses for HTTP errors
Run Code Online (Sandbox Code Playgroud)
似乎引用的"空字符串"没有让位于该ErrorDocument指令,并且Apache将此配置行解析为具有单个参数的指令.
在阅读Apache的配置文件语法并在文档中查找"space"和"quote"之后,我找不到令人满意的解释,或者将空字符串作为参数的任何提示.它仅在包含空格的参数的情况下提及引号.
ErrorDocument正如Apache的自定义错误响应所示,
ErrorDocument指令的语法是:
Run Code Online (Sandbox Code Playgroud)ErrorDocument <3-digit-code> <action>该行动将被视为:
- 要重定向到的本地URL(如果操作以"/"开头).
- 要重定向到的外部URL(如果操作是有效的URL).
- 要显示的文本(如果不是上述内容).如果文本由多个单词组成,则必须用引号(")括起来.
在Apache的ErrorDocument指令中也有提到,
从2.4.13开始,可以在指令内使用表达式语法来生成动态字符串和URL.
我们应该可以使用ErrorDocument2.4.13中的表达式.
经过一些实验,我发现并非所有表达都有效ErrorDocument.但variable正如表达式中指定的那样,BNF符号可以解释为ErrorDocument,
variable ::= "%{" varname "}"
| "%{" funcname ":" funcargs "}"
Run Code Online (Sandbox Code Playgroud)
(rebackref可能也有效,但我不确定如何使用它ErrorDocument.)
现在我们只需要一些可以计算为空字符串的空变量或函数.
并且有一个空字符串表达式,以函数的形式,
unescapeUnescape
%hex编码的字符串,只留下编码的斜杠; 如果%00找到则返回空字符串
所以这是返回空响应体的解决方案,
ErrorDocument 200 %{unescape:%00}
Run Code Online (Sandbox Code Playgroud)
ErrorDocument为什么首先在问题中提到了一个非空的响应主体?
我在apache的ErrorDocument指令中找到了这个,
如果出现问题或错误,Apache httpd可以配置为执行以下四种操作之一:
- 输出一个简单的硬编码错误消息
- 输出自定义消息
- 内部重定向到本地URL路径以处理问题/错误
- 重定向到外部URL以处理问题/错误
由于未指定200的错误文档,Apache决定使用200的硬编码错误消息.
有关硬编码错误消息的详细信息不在文档中,必须在源代码中找到.但我想200没有这样的错误消息,所以我们有这个内部错误/配置错误的事情.
可以通过以下方式获得与问题中提到的完全相同的响应
ErrorDocument 200 default
Run Code Online (Sandbox Code Playgroud)
因为Apache的ErrorDocument指令提到了这一点,
此外,特殊值默认值可用于指定Apache httpd的简单硬编码消息.
| 归档时间: |
|
| 查看次数: |
6151 次 |
| 最近记录: |