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 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";

3 Responses to Nginx支持手機訪問(WAP/XHTML)相關配置

  1. Showfom says:

    那么復雜……

  2. lin says:

    怎么設才可以支持wap 的網頁,我現在打開是亂碼.
    Content-Type: application/xhtml+xml; charset=UTF-8
    這些我在網頁里都設了,用手機就是打不開,用網頁下載首頁亂碼

  3. rongton says:

    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;

    }

    }

發表評論

(required)

This site uses Akismet to reduce spam. Learn how your comment data is processed.