Nginx支持手机访问(WAP/XHTML)相关配置 【转】

1、判断手机用户

一般通过User-Agent来判断,从网上抄一抄,那些列出的都不错,我的配置里加上了Java、curl和Wget,方便调试和其它内部项目的抓取。

因为现在很多手机网关没有发送User-Agent,所以大部分手机发送的User-Agent到了网关就被过滤掉了,相当于是空值。经过抽样调 查,User-Agent为空且为手机用户比例比较大。有部分User-Agent为空的是一些蜘蛛或垃圾程序的造访,这些垃圾流量并不那么重要。希望手 机网关将来有相应的标准,不要发送空的User-Agent,就是发送一个字母也好啊。

如果应用有一个独立域名,也未必要做手机判断。譬如新浪有独立域名且深入人心,那它做不做跳转无关紧要。

nginx配置用穷举方式罗列各类手机User-Agent并把空User-Agent也转到手机应用里,非这些情况,则跳到帮助页面。

set $ismob 0;
if ( $http_user_agent ~ "^((.MIDP.)|(.WAP.)|(.UP.Browser.)|(.Smartphone.)|(.Obigo.)|(.Mobile.)|(.AU.Browser.)|(.wxd.Mms.)|(.WxdB.Browser.)|(.CLDC.)|(.UP.Link.)|(.KM.Browser.)|(.UCWEB.)|(.SEMC-Browser.)|(.Mini.)|(.Symbian.)|(.Palm.)|(.Nokia.)|(.Panasonic.)|(.MOT-.)|(.SonyEricsson.)|(.NEC-.)|(.Alcatel.)|(.Ericsson.)|(.BENQ.)|(.BenQ.)|(.Amoisonic.)|(.Amoi-.)|(.Capitel.)|(.PHILIPS.)|(.SAMSUNG.)|(.Lenovo.)|(.Mitsu.)|(.Motorola.)|(.SHARP.)|(.WAPPER.)|(.LG-.)|(.LG/.)|(.EG900.)|(.CECT.)|(.Compal.)|(.kejian.)|(.Bird.)|(.BIRD.)|(.G900/V1.0.)|(.Arima.)|(.CTL.)|(.TDG.)|(.Daxian.)|(.DAXIAN.)|(.DBTEL.)|(.Eastcom.)|(.EASTCOM.)|(.PANTECH.)|(.Dopod.)|(.Haier.)|(.HAIER.)|(.KONKA.)|(.KEJIAN.)|(.LENOVO.)|(.Soutec.)|(.SOUTEC.)|(.SAGEM.)|(.SEC-.)|(.SED-.)|(.EMOL-.)|(.INNO55.)|(.ZTE.)|(.iPhone.)|(.Android.)|(.Windows CE.)|(Wget.)|(Java.)|(curl.)|(Opera.))$" )
{
set $ismob 1;
proxy_pass https://m.sudone.com;
}
if ( $http_user_agent ~ ^$ )
{
set $ismob 1;
proxy_pass https://m.sudone.com;
}
if ( $ismob = 0 )
{
rewrite "^.*$" https://help.m.sudone.com/ permanent;
}

2、Content-Type

手机浏览器和普通电脑访问页面有所不同,绝大多数手机不支持text/html这种Content-Type格式。在web服务方面,除了要做出合 适手机浏览的页面,另外一个重要的事情就是要把Content-Type弄对了。一般手机使用的是text/vnd.wap.wml和 application/xhtml+xml,听说text/vnd.wap.wml是老式手机专用,application/xhtml+xml是3g 标准指定的Content-Type,另外charset需要指明为UTF-8。

所以Content-Type就应像如下:

Content-Type: application/xhtml+xml; charset=UTF-8

这样就对了。

对于动态页面,Content-Type可以在程序里设定。

譬如php

header("Content-Type: application/xhtml+xml; charset=UTF-8")

jsp的话,把顶头的page改了就好

动态程序里的设定,到了nginx上默认会继承,所以不用太多考虑。nginx要做的一个是静态页面,另一个是302跳转。

静态页面的Content-Type改起来不麻烦,修改mime.types:

application/xhtml+xml                 html htm shtml;
application/xhtml+xml                 xml;

把需要的扩展名对应的类型改一改就好了。然后在nginx.conf里指定charset UTF-8。

麻烦的是301和302跳转,nginx中使用rewrite的redirect和permanent跳转的时候,Content-Type怎么改 都会是text/html,使用add_header,Content-Type变成了两行,没能达成目的。用代理到动态程序固然行,但性能和稳定性又成 了问题。最后查阅了nginx源码,发现这个text/html是写死的……

唉,第一次修改c代码:

我调试的这个nginx是0.7.30版的,文件:

vi ./src/http/ngx_http_special_response.c

568             //r->headers_out.content_type_len = sizeof("text/html") – 1;
569             //r->headers_out.content_type.len = sizeof("text/html") – 1;
570             //r->headers_out.content_type.data = (u_char *) "text/html";

把568 569 570这三行代码注释掉,就可以让nginx跳转时不发送Content-Type,我发现在电脑的IE/FF浏览器上没有Content-Type也能正常跳转。

当然,为了严谨一些,写上Content-Type吧,现在可以用add_header定义:
add_header Content-Type "text/html";

手机的就是:
add_header Content-Type "application/xhtml+xml";

原创文章,转载请注明: 转载自混沌

本文链接地址: Nginx支持手机访问(WAP/XHTML)相关配置 【转】