寻仙进不去了,log里显示这个Http servernginx return 3022, fi...

您的位置:
→ nginx 301 302重定向跳转配置教程
nginx 301 302重定向跳转配置教程
23:17:31来源:编辑: [
首先看一个完整代码示例,关于nginx 301 302跳转的。
301跳转设置:
listen 80;
rewrite ^/(.*) /$1
302跳转设置:
listen 80;
rewrite ^/(.*) /$1
在看下关于nginx 301 302跳转的详细说明文档
rewrite ^/(.*) /$1
last & 基本上都用这个Flag。
break & 中止Rewirte,不在继续匹配
redirect & 返回临时重定向的HTTP状态302
permanent & 返回永久重定向的HTTP状态301
Nginx的重定向用到了Nginx的HttpRewriteModule,下面简单解释以下如何使用的方法:
rewrite命令
nginx的rewrite相当于apache的rewriterule(大多数情况下可以把原有apache的rewrite规则加上引号就可以直接使用),它可以用在server,location 和IF条件判断块中,命令格式如下:
rewrite 正则表达式 替换目标 flag标记
flag标记可以用以下几种格式:
last & 基本上都用这个Flag。
break & 中止Rewirte,不在继续匹配
redirect & 返回临时重定向的HTTP状态302
permanent & 返回永久重定向的HTTP状态301
特别注意:
last和break用来实现URL重写,地址栏的URL地址不变,但是在服务器端访问的路径发生了变化;
redirect和permanent用来实现URL跳转,浏览器地址栏会显示跳转后的URL地址;
例如下面这段设定nginx将某个目录下面的文件重定向到另一个目录,$2对应第二个括号(.*)中对应的字符串:
location /download/ {
rewrite ^(/download/.*)/m/(.*)\..*$ $1/nginx-rewrite/$2.
nginx重定向的IF条件判断
在server和location两种情况下可以使用nginx的IF条件判断,条件可以为以下几种:
正则表达式
~ 为区分大小写匹配; !~为区分大小写不匹配
~* 为不区分大小写匹配;!~为不区分大小写不匹配
例如下面设定nginx在用户使用ie的使用重定向到/nginx-ie目录下:
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /nginx-ie/$1
文件和目录判断
-f和!-f判断是否存在文件
-d和!-d判断是否存在目录
-e和!-e判断是否存在文件或目录
-x和!-x判断文件是否可执行
例如下面设定nginx在文件和目录不存在的时候重定向:
if (!-e $request_filename) {
proxy_pass http://127.0.0.1;
返回http代码,例如设置nginx防盗链:
location ~* \.(gif|jpg|png|swf|flv)$ {
if ($invalid_referer) {
return 404;
关键词:nginx,重定向
03-0310-2208-2908-2908-2907-2707-2106-1604-0203-31
阅读本文后您有什么感想? 已有
人给出评价!
nginx(发音同engine x)是一款由俄罗斯程序员
Nginx 发布最新开发版 1.3.12,下载地址:
nginx(发音同 engine x)是一款轻量级的Web
Nginx (&engine x&) 是一个高性能
StarLee是一款图形界面的快速搭建nginx、PHP网
wnmp 是一个快速搭建Nginx 0.7.19、PHP 5.2.6
我们很高兴的宣布由淘宝网核心系统部开发的Te
Data redirect是一个附加模块,精确的打印监视
XArpC是一款字符界面版本的网络管理小工具。提
win10桌面美化工具是一款用于修改win10系统的
02-0109-2306-3006-0402-2604-0806-0404-0512-0102-28博客后台之后,在日志中发现大量的&无法在发送HTTP标头之后进行重定向&(Cannot redirect after HTTP headers have been sent)的错误信息。
检查代码发现问题是由下面的代码触发的:
IHttpHandler IHttpHandlerFactory.GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
context.Response.Redirect("/" +
context.Request.RawUrl.Substring(context.Request.RawUrl.LastIndexOf("/") + 1));
//后续也有context.Response.Redirect代码
return PageParser.GetCompiledPageInstance(newurl, path, context);
&无法在发送HTTP标头之后进行重定向&问题来源于Response.Redirect之后,又进行了Response.Redirect。
解决方法很简单:在Response.Redirect之后立即返回。
IHttpHandler IHttpHandlerFactory.GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
context.Response.Redirect("/" +
context.Request.RawUrl.Substring(context.Request.RawUrl.LastIndexOf("/") + 1));
return null;
为什么之前没有加return null呢?因为以前一直以为Response.Redirect会结束当前请求,不会执行Response.Redirect之后的代码。
现在残酷的现实说明了不完全是这样的,那问题背后的真相是什么?让我们来一探究竟。
由于微软公开了.NET Framework的源代码,现在无需再看Reflactor出来的代码,可以直接下载源代码用Visual Studio进行查看。
.NET Framework源代码下载链接:&(相关新闻:)
用Visual Studio打开DotNetReferenceSource\Source\ndp.sln,搜索HttpResponse.cs,找到Response.Redirect的实现代码:
public void Redirect(String url)
Redirect(url, true, false);
实际调用的是internal void Redirect(String url, bool endResponse, bool permanent) ,传给endResponse的值的确是true啊,为什么后面的代码还会执行?
进一步查看internal void Redirect()的实现代码(省略了无关代码):
internal void Redirect(String url, bool endResponse, bool permanent)
Page page = _context.Handler as P
if ((page != null) && page.IsCallback) {
// ... url处理
Clear(); //Clears all headers and content output from the buffer stream.
this.StatusCode = permanent ? 301 : 302; //进行重定向操作
_isRequestBeingRedirected = true;
var redirectingHandler = R
if (redirectingHandler != null) {
redirectingHandler(this, EventArgs.Empty);
if (endResponse)
End(); //结束当前请求
从上面的代码可以看出,我们要找的真相在End()方法中,继续看HttpResponse.End()的实现代码:
public void End() {
if (_context.IsInCancellablePeriod) {
AbortCurrentThread();
// when cannot abort execution, flush and supress further output
_endRequiresObservation = true;
if (!_flushing) { // ignore Reponse.End while flushing (in OnPreSendHeaders)
_ended = true;
if (_context.ApplicationInstance != null) {
_pleteRequest();
注意啦!真相浮现了!
以前一直以为的Response.Redirect会结束当前请求,就是上面的AbortCurrentThread()情况,如果将Response.Redirect放在try...catch中就会捕捉到ThreadAbortException异常。
通常情况下,我们在WebForms的Page或MVC的Controller中进行Redirect,_context.IsInCancellablePeriod的值为true,执行的是AbortCurrentThread(),所以不会遇到这个问题。
而我们现在的场景恰恰是因为_context.IsInCancellablePeriod的值为false,为什么会是false呢?
进一步看一下_context.IsInCancellablePeriod的实现:
private int _timeoutS // 0=non-cancelable, 1=cancelable, -1=canceled
internal bool IsInCancellablePeriod {
get { return (Volatile.Read(ref _timeoutState) == 1); }
根据上面的代码,触发这个问题的条件是_timeoutState的值要么是0,要么是-1,根据我们的实际情况,应该是0=non-cancelable。
再来看看我们的实际应用场景,我们是在实现IHttpHandlerFactory接口的GetHandler方法中进行Response.Redirect操作的,也就是说在这个阶段_timeoutState的值还没被设置(默认值就是0)。为了验证这个想法,继续看一下_timeoutState在哪个阶段设值的。
Shift+F12找到所有引用_timeoutState的地方,在HttpConext中发现了设置_timeoutState的方法BeginCancellablePeriod,实现代码如下:
internal void BeginCancellablePeriod() {
// It could be caused by an exception in OnThreadStart
if (Volatile.Read(ref _timeoutStartTimeUtcTicks) == -1) {
SetStartTime();
Volatile.Write(ref _timeoutState, 1);
然后再Shift+F12找到了在HttpApplication.ExecuteStep()中调用了BeginCancellablePeriod():
internal Exception ExecuteStep(IExecutionStep step, ref bool completedSynchronously)
if (step.IsCancellable) {
_context.BeginCancellablePeriod(); // request can be cancelled from this point
从上面的代码可以看出,当step.IsCancellable为true时,会调用BeginCancellablePeriod(),就不会出现这个问题。
而我们用到的IHttpHandlerFactory.GetHandler()所在的IExecutionStep的实现可能将IsCancellable设置为了false。
那IHttpHandlerFactory.GetHandler()是在哪个IExecutionStep的实现中调用的呢?
在园子里的一篇写得非常棒的博文()中找到了***&&MapHandlerExecutionStep:
当执行到MapHandlerExecutionStep时会执行如下代码获取最终执行请求:context.Handler = this._application.MapHttpHandler()。HttpApplication对象的MapHttpHandler方法将根据配置文件结合请求类型和URL以调用相应的IHttpHandlerFactory来获取HttpHandler对象。
我们再回到.NET Framework的源代码中看一看MapHandlerExecutionStep的实现:
// execution step -- map HTTP handler (used to be a separate module)
internal class MapHandlerExecutionStep : IExecutionStep {
private HttpApplication _
internal MapHandlerExecutionStep(HttpApplication app) {
_application =
void IExecutionStep.Execute() {
bool pletedSynchronously {
get { return true;}
bool IExecutionStep.IsCancellable {
get { return false; }
看到有没有?IExecutionStep.IsCancellable返回的值是false。
到此,水落石出,真相大白!
请看大屏幕&&
由于MapHandlerExecutionStep(调用IHttpHandlerFactory.GetHandler()的地方)返回的IsCancellable的值是false,于是在HttpApplication.ExecuteStep()执行时没有调用_context.BeginCancellablePeriod()&&也就是没有把_timeoutState设置为1,_context.IsInCancellablePeriod的值就是false。从而造成在Response.Redirect中进行Response.End()时没有执行AbortCurrentThread()(通常情况下都会执行这个)。于是代码继续执行,后面又来一次Response.Redirect,最终引发了&&&无法在发送HTTP标头之后进行重定向&(Cannot redirect after HTTP headers have been sent)。
阅读(...) 评论()随笔 - 39&
评论 - 44&
&&&&&&&&&&&
HTTP协议状态码表示的意思主要分为五类,大体是:&& ~~~~~~~~~~~~~~~~~~~~~~~~~~~~&& 1××  保留&& 2××  表示请求成功地接收&& 3××  为完成请求客户需进一步细化请求&& 4××  客户错误&& 5××  服务器错误&&
100 Continue 指示客户端应该继续请求。回送用于通知客户端此次请求已经收到,并且没有被服务器拒绝。 客户端应该继续发送剩下的请求数据或者请求已经完成,或者忽略回送数据。服务器必须发送 最后的回送在请求之后。
101 Switching Protocols 服务器依照***端请求,通过Upgrade头信息,改变当前连接的应用协议。服务器将根据Upgrade头立刻改变协议 在101回送以空行结束的时候。
Successful
================================= 200 OK 指示***端的请求已经成功收到,解析,接受。
201 Created 请求已经完成并一个新的返回资源被创建。被创建的资源可能是一个URI资源,通常URI资源在Location头指定。回送应该包含一个实体数据 并且包含资源特性以及location通过用户或者用户代理来选择合适的方法。实体数据格式通过煤体类型来指定即content-type头。最开始服务 器 必须创建指定的资源在返回201状态码之前。如果行为没有被立刻执行,服务器应该返回202。
202 Accepted 请求已经被接受用来处理。但是处理并没有完成。请求可能或者根本没有遵照执行,因为处理实际执行过程中可能被拒绝。
203 Non-Authoritative Information
204 No Content 服务器已经接受请求并且没必要返回实体数据,可能需要返回更新信息。回送可能包含新的或更新信息由entity-headers呈现。
205 Reset Content 服务器已经接受请求并且用户代理应该重新设置文档视图。
206 Partial Content 服务器已经接受请求GET请求资源的部分。请求必须包含一个Range头信息以指示获取范围可能必须包含If-Range头信息以成立请求条件。&
Redirection ================================== 300 Multiple Choices 请求资源符合任何一个呈现方式。
301 Moved Permanently 请求的资源已经被赋予一个新的URI。
302 Found 通过不同的URI请求资源的临时文件。 303 See Other
304 Not Modified 如果***端已经完成一个有条件的请求并且请求是允许的,但是这个文档并没有改变,服务器应该返回304状态码。304 状态码一定不能包含信息主体,从而通常通过一个头字段后的第一个空行结束。
305 Use Proxy 请求的资源必须通过代理(由Location字段指定)来访问。Location资源给出了代理的URI。
306 Unused
307 Temporary Redirect
Client Error
===================== 400 Bad Request 因为错误的语法导致服务器无法理解请求信息。
401 Unauthorized 如果请求需要用户验证。回送应该包含一个WWW-Authenticate头字段用来指明请求资源的权限。
402 Payment Required 保留状态码
403 Forbidden 服务器接受请求,但是被拒绝处理。
404 Not Found 服务器已经找到任何匹配Request-URI的资源。
405 Menthod Not Allowed Request-Line请求的方法不被允许通过指定的URI。
406 Not Acceptable
407 Proxy Authentication Required
408 Reqeust Timeout ***端没有提交任何请求在服务器等待处理时间内。
409 Conflict
411 Length Required 服务器拒绝接受请求在没有定义Content-Length字段的情况下。
412 Precondition Failed
413 Request Entity Too Large 服务器拒绝处理请求因为请求数据超过服务器能够处理的范围。服务器可能关闭当前连接来阻止***端继续请求。
414 Request-URI Too Long 服务器拒绝服务当前请求因为URI的长度超过了服务器的解析范围。
415 Unsupported Media Type 服务器拒绝服务当前请求因为请求数据格式并不被请求的资源支持。
416 Request Range Not Satisfialbe
417 Expectation Failed
Server Error =================================== 500 Internal Server Error 服务器遭遇异常阻止了当前请求的执行
501 Not Implemented 服务器没有相应的执行动作来完成当前请求。
502 Bad Gateway
503 Service Unavailable 因为临时文件超载导致服务器不能处理当前请求。
504 Gateway Timeout
505 Http Version Not Supported
阅读(...) 评论()

参考资料

 

随机推荐