nginx监听跳转非80端口

http://kinggoo.com/nginx-not-proxy-80.htm

Nginx通过80端口反向代理到Tomcat实现很简单,通过Jsp的request.getServerPort()获取到的端口号依然是80,而如果Nginx使用非80端口做反响代理时request.getServerPort()获取到的端口号返回依然会是80,这样边无法正确response.sendRedirect

String path = request.getContextPath(); 
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

这样response.sendRedirect会跳转到80端口去

解决办法:

修改proxy.conf获取你把代理的配置写到了nginx内,也可以在其内部修改

proxy_redirect          off;

# nginx非80端口处理 
proxy_set_header        Host $host:$server_port
# 获取真实IP 
proxy_set_header        X-Real-IP $remote_addr; 
# 获取代理者的真实ip 
proxy_set_header       X-Forwarded-For   $proxy_add_x_forwarded_for; 
client_max_body_size    10m; 
client_body_buffer_size 128k; 
proxy_connect_timeout   90; 
proxy_send_timeout      90; 
proxy_read_timeout      90; 
proxy_buffer_size       4k; 
proxy_buffers           4 32k; 
proxy_busy_buffers_size 64k; 
proxy_temp_file_write_size 64k;

nginx vhost内虚拟主机代理配置

location ~* "\.(jsp|do)$" { 
        proxy_pass http://kinggoo.ts;

# 使用include引入就可以了 
        include proxy.conf; 
}

参考帮助

Nginx内置变量含义

名称    版本    说明(变量列表来源于文件 ngx_http_variables ) 
$args    1.0.8    请求中的参数; 
$binary_remote_addr    1.0.8    远程地址的二进制表示 
$body_bytes_sent    1.0.8    已发送的消息体字节数 
$content_length    1.0.8    HTTP请求信息里的"Content-Length"; 
$content_type    1.0.8    请求信息里的"Content-Type"; 
$document_root    1.0.8    针对当前请求的根路径设置值; 
$document_uri    1.0.8    与$uri相同; 
$host    1.0.8    请求信息中的"Host",如果请求中没有Host行,则等于设置的服务器名; 
$hostname    1.0.8     
$http_cookie    1.0.8    cookie 信息 
$http_post    1.0.8     
$http_referer    1.0.8    引用地址 
$http_user_agent    1.0.8    客户端代理信息 
$http_via    1.0.8     最后一个访问服务器的Ip地址。http://www.cnblogs.com/deng02/archive/2009/02/11/1387911.html
$http_x_forwarded_for    1.0.8     相当于网络访问路径。http://www.cnblogs.com/craig/archive/2008/11/18/1335809.html 
$is_args    1.0.8     
$limit_rate    1.0.8    对连接速率的限制; 
$nginx_version    1.0.8     
$pid    1.0.8     
$query_string    1.0.8    与$args相同; 
$realpath_root    1.0.8     
$remote_addr    1.0.8    客户端地址; 
$remote_port    1.0.8    客户端端口号; 
$remote_user    1.0.8    客户端用户名,认证用; 
$request    1.0.8    用户请求 
$request_body    1.0.8     
$request_body_file    1.0.8    发往后端的本地文件名称 
$request_completion    1.0.8     
$request_filename    1.0.8    当前请求的文件路径名 
$request_method    1.0.8    请求的方法,比如"GET"、"POST"等; 
$request_uri    1.0.8    请求的URI,带参数; 
$scheme    1.0.8     所用的协议,比如http或者是https,比如rewrite^(.+)$$scheme://example.com$1redirect; 
$sent_http_cache_control    1.0.8     
$sent_http_connection    1.0.8     
$sent_http_content_length    1.0.8     
$sent_http_content_type    1.0.8     
$sent_http_keep_alive    1.0.8     
$sent_http_last_modified    1.0.8     
$sent_http_location    1.0.8     
$sent_http_transfer_encoding    1.0.8     
$server_addr    1.0.8    服务器地址,如果没有用listen指明服务器地址,使用这个变量将发起一次系统调用以取得地址(造成资源浪费); 
$server_name    1.0.8    请求到达的服务器名; 
$server_port    1.0.8    请求到达的服务器端口号; 
$server_protocol    1.0.8    请求的协议版本,"HTTP/1.0"或"HTTP/1.1"; 
$uri    1.0.8    请求的URI,可能和最初的值有不同,比如经过重定向之类的 
名称    版本    说明(变量列表来源于文件 ngx_http_variables ) 
$args    1.0.8    请求中的参数; 
$binary_remote_addr    1.0.8    远程地址的二进制表示 
$body_bytes_sent    1.0.8    已发送的消息体字节数 
$content_length    1.0.8    HTTP请求信息里的"Content-Length"; 
$content_type    1.0.8    请求信息里的"Content-Type"; 
$document_root    1.0.8    针对当前请求的根路径设置值; 
$document_uri    1.0.8    与$uri相同; 
$host    1.0.8    请求信息中的"Host",如果请求中没有Host行,则等于设置的服务器名; 
$hostname    1.0.8     
$http_cookie    1.0.8    cookie 信息 
$http_post    1.0.8     
$http_referer    1.0.8    引用地址 
$http_user_agent    1.0.8    客户端代理信息 
$http_via    1.0.8     最后一个访问服务器的Ip地址。http://www.cnblogs.com/deng02/archive/2009/02/11/1387911.html
$http_x_forwarded_for    1.0.8     相当于网络访问路径。http://www.cnblogs.com/craig/archive/2008/11/18/1335809.html 
$is_args    1.0.8     
$limit_rate    1.0.8    对连接速率的限制; 
$nginx_version    1.0.8     
$pid    1.0.8     
$query_string    1.0.8    与$args相同; 
$realpath_root    1.0.8     
$remote_addr    1.0.8    客户端地址; 
$remote_port    1.0.8    客户端端口号; 
$remote_user    1.0.8    客户端用户名,认证用; 
$request    1.0.8    用户请求 
$request_body    1.0.8     
$request_body_file    1.0.8    发往后端的本地文件名称 
$request_completion    1.0.8     
$request_filename    1.0.8    当前请求的文件路径名 
$request_method    1.0.8    请求的方法,比如"GET"、"POST"等; 
$request_uri    1.0.8    请求的URI,带参数; 
$scheme    1.0.8     所用的协议,比如http或者是https,比如rewrite^(.+)$$scheme://example.com$1redirect; 
$sent_http_cache_control    1.0.8     
$sent_http_connection    1.0.8     
$sent_http_content_length    1.0.8     
$sent_http_content_type    1.0.8     
$sent_http_keep_alive    1.0.8     
$sent_http_last_modified    1.0.8     
$sent_http_location    1.0.8     
$sent_http_transfer_encoding    1.0.8     
$server_addr    1.0.8    服务器地址,如果没有用listen指明服务器地址,使用这个变量将发起一次系统调用以取得地址(造成资源浪费); 
$server_name    1.0.8    请求到达的服务器名; 
$server_port    1.0.8    请求到达的服务器端口号; 
$server_protocol    1.0.8    请求的协议版本,"HTTP/1.0"或"HTTP/1.1"; 
$uri    1.0.8    请求的URI,可能和最初的值有不同,比如经过重定向之类的 
名称    版本    说明(变量列表来源于文件 ngx_http_variables ) 
$args    1.0.8    请求中的参数; 
$binary_remote_addr    1.0.8    远程地址的二进制表示 
$body_bytes_sent    1.0.8    已发送的消息体字节数 
$content_length    1.0.8    HTTP请求信息里的"Content-Length"; 
$content_type    1.0.8    请求信息里的"Content-Type"; 
$document_root    1.0.8    针对当前请求的根路径设置值; 
$document_uri    1.0.8    与$uri相同; 
$host    1.0.8    请求信息中的"Host",如果请求中没有Host行,则等于设置的服务器名; 
$hostname    1.0.8     
$http_cookie    1.0.8    cookie 信息 
$http_post    1.0.8     
$http_referer    1.0.8    引用地址 
$http_user_agent    1.0.8    客户端代理信息 
$http_via    1.0.8     最后一个访问服务器的Ip地址。http://www.cnblogs.com/deng02/archive/2009/02/11/1387911.html
$http_x_forwarded_for    1.0.8     相当于网络访问路径。http://www.cnblogs.com/craig/archive/2008/11/18/1335809.html 
$is_args    1.0.8     
$limit_rate    1.0.8    对连接速率的限制; 
$nginx_version    1.0.8     
$pid    1.0.8     
$query_string    1.0.8    与$args相同; 
$realpath_root    1.0.8     
$remote_addr    1.0.8    客户端地址; 
$remote_port    1.0.8    客户端端口号; 
$remote_user    1.0.8    客户端用户名,认证用; 
$request    1.0.8    用户请求 
$request_body    1.0.8     
$request_body_file    1.0.8    发往后端的本地文件名称 
$request_completion    1.0.8     
$request_filename    1.0.8    当前请求的文件路径名 
$request_method    1.0.8    请求的方法,比如"GET"、"POST"等; 
$request_uri    1.0.8    请求的URI,带参数; 
$scheme    1.0.8     所用的协议,比如http或者是https,比如rewrite^(.+)$$scheme://example.com$1redirect; 
$sent_http_cache_control    1.0.8     
$sent_http_connection    1.0.8     
$sent_http_content_length    1.0.8     
$sent_http_content_type    1.0.8     
$sent_http_keep_alive    1.0.8     
$sent_http_last_modified    1.0.8     
$sent_http_location    1.0.8     
$sent_http_transfer_encoding    1.0.8     
$server_addr    1.0.8    服务器地址,如果没有用listen指明服务器地址,使用这个变量将发起一次系统调用以取得地址(造成资源浪费); 
$server_name    1.0.8    请求到达的服务器名; 
$server_port    1.0.8    请求到达的服务器端口号; 
$server_protocol    1.0.8    请求的协议版本,"HTTP/1.0"或"HTTP/1.1"; 
$uri    1.0.8    请求的URI,可能和最初的值有不同,比如经过重定向之类的 名称 版本 说明(变量列表来源于文件 ngx_http_variables ) 
$args 1.0.8 请求中的参数; 
$binary_remote_addr 1.0.8 远程地址的二进制表示 
$body_bytes_sent 1.0.8 已发送的消息体字节数 
$content_length 1.0.8 HTTP请求信息里的"Content-Length"; 
$content_type 1.0.8 请求信息里的"Content-Type"; 
$document_root 1.0.8 针对当前请求的根路径设置值; 
$document_uri 1.0.8 与$uri相同; 
$host 1.0.8 请求信息中的"Host",如果请求中没有Host行,则等于设置的服务器名; 
$hostname 1.0.8  
$http_cookie 1.0.8 cookie 信息 
$http_post 1.0.8  
$http_referer 1.0.8 引用地址 
$http_user_agent 1.0.8 客户端代理信息 
$http_via 1.0.8 最后一个访问服务器的Ip地址。http://www.cnblogs.com/deng02/archive/2009/02/11/1387911.html 
$http_x_forwarded_for 1.0.8 相当于网络访问路径。http://www.cnblogs.com/craig/archive/2008/11/18/1335809.html 
$is_args 1.0.8  
$limit_rate 1.0.8 对连接速率的限制; 
$nginx_version 1.0.8  
$pid 1.0.8  
$query_string 1.0.8 与$args相同; 
$realpath_root 1.0.8  
$remote_addr 1.0.8 客户端地址; 
$remote_port 1.0.8 客户端端口号; 
$remote_user 1.0.8 客户端用户名,认证用; 
$request 1.0.8 用户请求 
$request_body 1.0.8  
$request_body_file 1.0.8 发往后端的本地文件名称 
$request_completion 1.0.8  
$request_filename 1.0.8 当前请求的文件路径名 
$request_method 1.0.8 请求的方法,比如"GET"、"POST"等; 
$request_uri 1.0.8 请求的URI,带参数; 
$scheme 1.0.8 所用的协议,比如http或者是https,比如rewrite^(.+)$$scheme://example.com$1redirect; 
$sent_http_cache_control 1.0.8  
$sent_http_connection 1.0.8  
$sent_http_content_length 1.0.8  
$sent_http_content_type 1.0.8  
$sent_http_keep_alive 1.0.8  
$sent_http_last_modified 1.0.8  
$sent_http_location 1.0.8  
$sent_http_transfer_encoding 1.0.8  
$server_addr 1.0.8 服务器地址,如果没有用listen指明服务器地址,使用这个变量将发起一次系统调用以取得地址(造成资源浪费); 
$server_name 1.0.8 请求到达的服务器名; 
$server_port 1.0.8 请求到达的服务器端口号; 
$server_protocol 1.0.8 请求的协议版本,"HTTP/1.0"或"HTTP/1.1"; 
$uri 1.0.8 请求的URI,可能和最初的值有不同,比如经过重定向之类的

nginx内置变量转自:http://blog.sina.com.cn/s/blog_644eb9350101cuzm.html

版权声明:

转载原创文章请注明,文章出处:http://kinggoo.com
原文地址:http://kinggoo.com/nginx-not-proxy-80.htm
 
http://www.ituring.com.cn/article/48042

Tomcat前端配置一个HTTP服务器应该是大部分应用的标配了,基本思路就是所有动态请求都反向代理给后端的Tomcat,HTTP服务器来处理静态请求,包括图片、js、css、html以及xml等。这样可以让你的应用的负载能力提高很多,前端这个HTTP服务器主流用的最多的当属Apache HTTP Server和nginx。今天这篇文章主要讲解的是这种组合的方式的前提下,后端的Tomcat中的app在301跳转的时候遇到的一个问题。

问题

先把问题说清楚,前端nginx占用81端口,因为80干了别的,暂时懒得停80的应用,暂时修改为81端口而已。然后Tomcat占用8080端口,具体配置如下(只是截取了server中的一段):

location /app1/ {
    index index.jsp index.html index.html index.shtml;
    proxy_pass http://localhost:8080/app1/;

    proxy_set_header   Host             $host;
     proxy_set_header   X-Real-IP        $remote_addr;
    proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
}

location ~* ^.+\.(png|jpg|jpeg|gif|ico|css|js|xml)$ {
    root /home/gap/app/apache-tomcat-5.5.14/webapps;
}

上面的代码只是简单举例,其中处理静态内容的部分也可以用目录alias或者root的方式去处理,效果应该一样的,但是具体区别我也没深入了解,不过这不是今天的重点。在这个配置下出现的问题就是当访问http://host:81/app1/Login.do的时候,登录成功需要301跳转到用户中心页面,然后跳转的地址本应该是http://host:81/app1/userindex.do,但是结果不太尽如人意,浏览器实际出现的地址http://host/app1/userindex.do。这里面的问题就是81端口没了,跑80端口去了,自然就404了。扯了一大段,这就是今天想说的问题。

问题出现了,自然得分析原因,由于我们这个项目中需要支持ssl,使用了Struts1.2的Framework,于是采用了SecurePlugIn(想了解的可以参照SSLExt Command 2.3节)的插件来处理。那么我首先怀疑是不是这个东西在作怪,看了下配置文件这个插件的enable都直接为false。看来不是这个插件作怪了,那么在不是应用本身逻辑在作怪的话那么可能是服务器配置有问题了,这个时候就应该直接从http请求开始分析了。

首先我打开chrome,然后来分析这次request发生了什么(打开开发者工具中的Network面板),能发现的基本就是请求Login.do是没问题的,但是Login.do之后发生的301重定向是错误的,一个重要的线索就是Login.do的请求中response中的Location的值是http://host/usercenter.do,这里丢掉了端口号。这个地方的具体原因后边会提到,先说下解决思路。

解决思路可以有两个,第一个就是nginx是可以利用proxy_redirect来修改response的Location和Refresh的值,Location自然可以被重新修改为81端口的地址,第二个就是找到是谁把Location搞错了,修改这个地方别搞错Location就行了。

解决思路1:利用nginx的proxy_redirect

这个思路其实有点偏重解决问题型,就是我看到这里错了,原因不纠结,我让你好使就可以了。可能好多人都是这个思路,毕竟解决问题是首要目的。

很多人在配置nginx的时候,习惯参考官方wiki的Full Example (taken from Nginx site),来做一些配置,参考这个肯定比参考baidu搜索出来的文档要靠谱很多,建议不了解每个属性的可以来参照下这个官方示例。这个配置里面proxy_redirect的属性为off,很多人应该没有问过为什么就直接根据人家来做了,之所以这样下结论是因为我看到太多国内人的集成例子中都是这样设置的了。我这里也是这样设置的,以前也倒是没想起来问下为啥,的确不太符合我的风格。反正服务器是这样配置的,现在是出来问题了,我们先来看下这个属性能做什么。

首先看官方文档Reference:proxy_redirect的说明:

Sets a text that should be changed in the header fields “Location” and “Refresh” of a response from the proxied server. Suppose a proxied server returned the header field “Location: http://localhost:8000/two/some/uri/”.

基本意思就是修改代理服务器(也就是此时的nginx)的response的头信息里面的LocationRefresh的值,按照这个解释的话我们的问题肯定就迎刃而解了,因为现在遇到的问题就是这个能够修改的两个中的一个Location出了问题,那么下面的代码就可以解决问题

proxy_redirect     http://host http://host:81;

这样重启sudo nginx -s reload然后再访问应该就ok了。其实你google搜索nginx proxy_redirect 重定向有好多这样的例子和这个解决方式是一样的,就不细说了,如果有人想了解的可以自己参照nginx官方文档和结合例子来操作下试试就可以理解了。

解决思路2:找到问题原因,修改出错的地方解决

根据上个思路解决了问题以后,一点都没如释重负的感觉,反而各个地方都觉得很空的感觉,因为有好几个疑问没解决,其中包括为啥是80而不是81或者8080没道理?这个Location是不是应该nginx来重写,修改掉那个跳转错的地方是不是比这个思路会更好?

那就先来分析下问题的原因:既然response的Locaiton不对,那么首先想到的就是这个Location是谁构造出来的,了解HTTP协议的人应该都知道,request中的header都是client(浏览器等)构造好发送给服务器的,服务器收到请求以后构造response信息返回给client。那么这样Location这个值肯定就是nginx或者Tomcat给搞出的问题了,这个地方nginx只是一个proxy server,那么response肯定是Tomcat发给nginx的,也就是说我们应该从Tomcat下手来分析这个问题。

首先我就看了下Tomcat的官方文档 Proxy Support,这里面对这个介绍如下:

The proxyName and proxyPort attributes can be used when Tomcat is run behind a proxy server. These attributes modify the values returned to web applications that call the request.getServerName() and request.getServerPort() methods, which are often used to construct absolute URLs for redirects. Without configuring these attributes, the values returned would reflect the server name and port on which the connection from the proxy server was received, rather than the server name and port to whom the client directed the original request.

意思就是proxyPort的属性就是用来我这种nginx做前端代理服务器Tomcat在后端处理动态请求的情况的。修改属性的值可以作用于应用的两个方法,主要用于绝对路径和重定向之用。如果不配置的话,可能会不对头。那么既然是这里不对头,我就先把server.xml中我这个http的connector的配置加入了proxyPort="81",重启Tomcat,然后把nginx上步骤的修改注释掉,重启测试。结果基本如所料,完全正常跳转了。

事情到了这个时候,其实问题基本明了了,不过我还是对这个Tomcat为啥默认解析了80端口很是疑惑。我下载了Tomcat的source来看下问题究竟,看了以后用通俗的语言来表述的话就是这样:如果默认不配置proxyPort默认为0,然后在构造response的时候判断如果proxyPort为0那么就不添加端口,不添加端口当然就默认走了80端口,源代码如下:

// FIXME: the code below doesnt belongs to here, 
// this is only have sense 
// in Http11, not in ajp13..
// At this point the Host header has been processed.
// Override if the proxyPort/proxyHost are set 
String proxyName = connector.getProxyName();
int proxyPort = connector.getProxyPort();
if (proxyPort != 0) {
    req.setServerPort(proxyPort);
}
if (proxyName != null) {
    req.serverName().setString(proxyName);
}

到了这里就真相大白了,心里也没结了,一块石头终于落地了。

总结

也就是说Tomcat在设计的时候是对这种代理服务器和Tomcat集成的情况做了考虑,80端口之所以没问题是因为port为空,浏览器会默认走80端口,如果nginx这代理服务器不是80这个端口应该需要配置proxyPort的属性的,这样就不会遇到这个问题。

那么基于这个来总结的话,两种解决方式都可以,不过修改Tomcat配置文件的方式是我最推荐的,因为这个思路看起来是又合理、又易于理解。我的感觉就是谁的事情谁来解决比较好,nginx作为proxy server 你就只需要做你的静态文件的解析,和把动态请求方向代理的服务器就可以了,既然Tomcat把这个信息构造错了,人家也有提供了解决方案,就根据你的情况合理配置就可以了。

一直以来自己是个特别较真的人,各种事情都是,希望每个人在解决问题的时候不要仅限于解决了问题就ok吧,更多的去了解问题的真相才会进步更快,例如这个问题其实有一个必要前提是需要了解一些HTTP的协议的基础知识,如果不了解的话可能你不会很快判断出Location出了问题,你可能也不会很快知道response是谁构造错的。建议大家都读下《HTTP权威指南》,每个做web开发的工程师都应该拥有这本书,可以大概先看一遍了解,后续需要就拿出来作为工具书查阅资料。如果作为工具书的话,那就强烈推荐大家购买图灵推出的《HTTP权威指南》电子版,我都把我的纸质书卖了换了电子版了,买了都说好啊。不过顺带说句图灵购买也需要输入个兑换码才能送银子,这体验不好,因为总是忘记,着急买书的都会忘记,建议改进下啊。

 

 

http://blog.csdn.net/xzknet/article/details/6342018

nginx可以很方便的配置成反向代理服务器

 

server {
listen 80;
server_name localhost;

location / {
    proxy_pass http://147.16.24.175:9500 ;
    proxy_set_header Host $host:80;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Via "nginx";

}
}

 

但是如果nginx的监听端口不是默认的80端口,改为其他端口如81端口。

后端服务器中request.getServerPort()无法获得正确的端口,返回的仍然是80;

在response.sendRedirect()时,客户端可能无法获得正确的重定向url。

正确的配置方法为

在 $host之后加上端口号,如$host:81

server {
        listen       83;
        server_name  localhost;

        location / {
         proxy_pass  
http://147.16.24.175:9500 ;
         proxy_set_header   Host             $host:83;
         proxy_set_header   X-Real-IP        $remote_addr;
         proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
         proxy_set_header Via    "nginx";

        }
 }

==============

 

 

http://www.vfeelit.com/121.html

Nginx中反向代理后端使用非80端口时遇到的问题与解决

Nginx反向代理图

Nginx反向代理图

用户访问http://domain.com/images,经过前端代理后被转换为对后端以http://domain.com:8080/images的请求,后端接收到请求后得知images是一个目录(对目录自动加斜线,Apache也是一样行为),所以后端Nginx自动进行一次重定向,重定向地址为http://domain.com:8080/images/,这个定向发送到前端,前端再送回到访问者,这样访问则以http://domain.com:8080/images/对前端重新发起请求,但是前端8080端口并没有开放,导致无法访问, 如果前端链接后端时使用的也是80端口,那么就不存在这个问题了。

 

Nginx返回的URL

Nginx返回的URL


可以证实,客户端以http://domain.com:8080/images/重新发起请求。

 

这个问题的解决就在于后端返回http://domain.com:8080/images/这样的链接时,先把其修改为http://domain.com/images/,然后再送回到客户端,那么问题就可以完美解决了。

Nginx中解决此问题的是proxy_redirect指令,详细的内容请参看http://wiki.nginx.org/NginxHttpProxyModule#proxy_redirect。在前端反向代理上,如下设置:

location / {
      proxy_pass http://x.x.x.x:8080/;
      proxy_redirect http://$host:8080/ http://$host/;
      proxy_set_header Host $host;
      proxy_set_header X-Forwarded-For $remote_addr;
}

这里把http://$host:8080/替换为http://$host/,这样前端经过修改后,返回给客户端的地址就正确了。

这个问题的产生是当URL指向一个目录并且在最后没有包含“/”时,Nginx内部会自动的做一个301重定向,由此产生了一些扩展知识,这时的这个301重定向有两种情况:
1、 server_name_in_redirect on,URL重定向为:server_name 中的第一个域名+目录名+/
2、 server_name_in_redirect off,URL重定向为:原URL中的域名+目录名+/

很多情况下,为了统一不带www和带www的域访问,通常使用301定向到其中一个域的访问,比如把domain.com的访问重定向到www.domain.com的访问,所以配置中一般如下:

listen 80;
server_name domain.com www.domain.com;
if ($host = 'domain.com') {
    rewrite ^/(.*)$ http://www.domain.com/$1 permanent;
}

当没有这个if的判断并且server_name_in_redirect on(默认)时,访问http://www.domain.com/images时,客户端要求重新以http://domain.com/images/来访问,这种情况看起来就有点奇怪了。

如果存在这个if语句,那么访问http://domain.com/images时,这个if语句先起作用还是内部的加斜线的重定向起作用呢,试验一下就出结果:

[root@domain.com ~]# curl -I http://domain.com/images
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Mon, 06 Aug 2012 14:36:22 GMT
Content-Type: text/html
Content-Length: 184
Connection: keep-alive
Location: http://www.domain.com/images

[root@domain.com ~]# curl -I http://www.domain.com/images
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Mon, 06 Aug 2012 14:39:09 GMT
Content-Type: text/html
Content-Length: 184
Location: http://www.domain.com/images/
Connection: keep-alive

server_name_in_redirect为on,URL重定向为:server_name 中的第一个域名+目录名+/,来证明一下是否如此(server_name domain.com www.domain.com):

[root@domain.com conf]# curl -I http://www.domain.com/images
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Mon, 06 Aug 2012 14:50:41 GMT
Content-Type: text/html
Content-Length: 184
Location: http://domain.com/images/
Connection: keep-alive

确实,它以server_name的第一个域重新发起了请求,而更换为server_name_in_redirect为off后,它又以原URL中的域名发起请求,看起来这个参数设置为off是合理的默认设置,不过在Nginx的早期版本中它默认是on的,后来默认值改成了off。

原创文章,转载务必保留出处。
永久链接: http://www.vfeelit.com/121.html

posted @ 2015-01-05 11:38  陳聽溪  阅读(2004)  评论(0编辑  收藏  举报