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 http://m.sudone.com;
}
if ( $http_user_agent ~ ^$ )
{
set $ismob 1;
proxy_pass http://m.sudone.com;
}
if ( $ismob = 0 )
{
rewrite "^.*$" http://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";
那么复杂……
怎么设才可以支持wap 的网页,我现在打开是乱码.
Content-Type: application/xhtml+xml; charset=UTF-8
这些我在网页里都设了,用手机就是打不开,用网页下载首页乱码
user www www;
worker_processes 4;
error_log logs/nginx_error.log crit;
pid /usr/local/nginx/nginx.pid;
#Specifies the value for maximum file descriptors that can be opened by this process.
worker_rlimit_nofile 51200;
events
{
use epoll;
worker_connections 51200;
}
http
{
include mime.types;
default_type application/octet-stream;
charset utf-8;
server_names_hash_bucket_size 128;
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;
sendfile on;
tcp_nopush on;
keepalive_timeout 60;
tcp_nodelay on;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml;
gzip_vary on;
#limit_zone crawler $binary_remote_addr 10m;
upstream wwwtodayinns{
server http://www.todayinns.com;
index index.php index.html index.htm;
root /var/www/html;
error_page 404 = /notfound.html;
location /{
rewrite "^/sns$" /sns.php last;
rewrite "^/sns/create$" /sns.php?do=create last;
rewrite "^/sns/([1-9][0-9]*)$" /sns.php?_id=$1 last;
rewrite "^/news$" /news.php last;
rewrite "^/news/([1-9][0-9]*)$" /news.php?_id=$1 last;
rewrite "^/news/([a-zA-Z][0-9a-zA-Z]*)$" /news.php last;
rewrite "^/book$" /book.php last;
rewrite "^/book/([a-zA-Z]+)$" /book.php?_mod=$1 last;
rewrite "^/comment/([1-9][0-9]*)$" /comment.php?_id=$1 last;
rewrite "^/branch$" /branch.php last;
rewrite "^/branch/([1-9][0-9]*)$" /branch.php?_id=$1 last;
rewrite "^/admin$" /admin/admin.php last;
rewrite "^/admin/([a-z]+)$" /admin/admin.php?_mod=$1 last;
rewrite "^/admin/([a-z]+)/([^/]+)$" /admin/admin.php?_mod=$1&_id=$2 last;
rewrite "^/admin/([a-z]+)/([a-z]+)/([^/]+)$" /admin/admin.php?_mod=$1&_id=$2&_type=$3 last;
}
location ~ .*\.(php|php5)?$
{
#fastcgi_pass unix:/tmp/php-cgi.sock;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fcgi.conf;
}
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
}
location ~ .*\.(js|css)?$
{
expires 1h;
}
log_format access '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $http_x_forwarded_for';
access_log logs/access.log access;
}
upstream waptodayinns{
server wap.todayinns.com;
server_name http://www.todayinns.com;
index index.php index.html index.htm;
root /var/www/html;
}
}