我的服务器出现问题。我有四个到我的动态网页不同网站的入站链接,看起来像这样:
myurl.com/default/Site%3Fid%3D13
它们应该是这样的:
myurl.com/default/Site?id=13
我知道%3F
是?
符号的转义序列,%3D
是等号的转义序列。但当我使用这些链接时,我确实得到了错误400。我该怎么办?
这四个链接适用于不同的网站,我想随着时间的推移,会有更多这样的链接。因此,一个解决方案将是完美的。
大约一年前,nginx-ru邮件列表上也提出了一个完全相同的问题:
http://mailman.nginx.org/pipermail/nginx-ru/2013-February/050200.html
最有帮助的回应,由Nginx公司的员工/开发人员,ВалиинБариаийаайицилана:
http://mailman.nginx.org/pipermail/nginx-ru/2013-February/050209.html
Слизафайла。位置。
翻译:
如果请求以这样的形式出现,那么这些不再是参数,而是请求文件的名称。另一件事是,如文档所述,位置匹配是针对规范化的URI执行的。
他建议的解决方案,转化为SO的问题示例,将是:
location /default/Site? {
rewrite ?(.*)$ /default/Site?$1? last;
}
location = /default/Site {
[...]
}
以下示例会将所有看起来错误的请求(定义为请求文件名中有?
,在请求中编码为%3F
)重定向到看起来不太错误的请求,而不管URL如何。
(请注意,正如其他地方正确建议的那样,您一开始就不应该获得这些格式错误的链接,因此,只有在您无法以其他方式更正格式错误的连接,并且您知道此类请求是由有效代理尝试的情况下,才可将其作为最后手段。)
server {
listen [::]:80;
server_name localhost;
rewrite ^/([^?]*)?(.*)$ /$1?$2? permanent;
location / {
return 200 "id is $arg_idn";
}
}
这是一个如何运作的例子—当遇到一个看起来错误的请求时,会用一个301 Moved Permanently
响应和一个假定正确的Location
响应头进行更正尝试,这将使浏览器自动将请求重新发布到新提供的位置:
opti# curl -6v "http://localhost/default/Site%3Fid%3D13"
* About to connect() to localhost port 80 (#0)
* Trying ::1...
* connected
* Connected to localhost (::1) port 80 (#0)
> GET /default/Site%3Fid%3D13 HTTP/1.1
> User-Agent: curl/7.26.0
> Host: localhost
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Server: nginx/1.4.1
< Date: Wed, 15 Jan 2014 17:09:25 GMT
< Content-Type: text/html
< Content-Length: 184
< Location: http://localhost/default/Site?id=13
< Connection: keep-alive
<
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.4.1</center>
</body>
</html>
* Connection #0 to host localhost left intact
* Closing connection #0
请注意,对于外观正确的请求,不会进行任何更正尝试:
opti# curl -6v "http://localhost/default/Site?id=13"
* About to connect() to localhost port 80 (#0)
* Trying ::1...
* connected
* Connected to localhost (::1) port 80 (#0)
> GET /default/Site?id=13 HTTP/1.1
> User-Agent: curl/7.26.0
> Host: localhost
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.4.1
< Date: Wed, 15 Jan 2014 17:09:30 GMT
< Content-Type: application/octet-stream
< Content-Length: 9
< Connection: keep-alive
<
id is 13
* Connection #0 to host localhost left intact
* Closing connection #0
URL完全有效。它包含的转义字符就是转义字符。这很好。
这样做的目的是,您实际上可以有一个请求名称(在大多数情况下对应于磁盘上的文件名),它是Site?id=13
而不是Site
,其余的作为查询字符串。
我认为在文件名中包含字符是不好的做法,这样做是必要的。然而,在URL参数中,这可能是非常必要的。
尽管如此,请求URL是有效的,可能不是你想要的。因此,这建议你应该在任何人一开始就收到错误URL的地方更正错误。
我真的不明白为什么你会得到一个错误400;你应该得到一个错误404。但这取决于你的设置。
也有一些情况,尤其是nginx,主要涉及在多个级别传递整个URL和URL部分(例如反向代理、从URL匹配正则表达式并将其用作变量等),可能会发生此类错误。但要验证并修复它,我们需要了解更多关于您的设置。