Nginx、PCRE和中文URL(UTF8編碼)rewrite路徑重寫匹配問題

最近遇到了使用Nginx 重寫中文UTF8編碼路徑的問題。 才發現默認狀況下Nginx的rewrite是不支持UTF8匹配的。 好比:html

rewrite ^/(..)$ /2個字符文章.html break; #用2個點
能夠匹配到 /ab 或 /51, 但 /漢字 是匹配不到的。 我測試了一下, 要匹配兩個字的 /漢字 路徑, 得用nginx

rewrite ^/(……)$ /2個漢字文章.html break; #要用六個點測試

若是要讓 ^/(..)$ 匹配到2個漢字字符,得開啓Nginx對UTF8字符的正則支持, 準確點說是開啓Nginx使用的PCRE庫的對UTF8字符的支持。由於Nginx的rewrite模塊是調用PCRE來處理正則的。 若是PCRE沒有問題,Nginx支持UTF8編碼的重寫樣式是:this

rewrite "(*UTF8)^/(..)$" /2個字符文章.html break;
#注意(*UTF8)前綴和引號的加入。
編碼

由於PCRE只有7.9以上的版本才支持這個(*UTF8)開頭,因此係統上的PCRE必定要使用7.9以上的版本。 另外,編譯PCRE時必定要開啓UTF8的支持。 即便用(–enable-utf8)參數。 檢查系統的PCRE版本和是否支持UTF8編碼可使用
pcretest -C
命令。執行後會顯示以下的報告:
url

PCRE version 8.13 2011-08-16
Compiled with
UTF-8 support
Unicode properties support
Newline sequence is LF
R matches all Unicode newlines
Internal link size = 2
POSIX malloc threshold = 10
Default match limit = 10000000
Default recursion depth limit = 10000000
Match recursion uses stackspa

顯示「UTF-8 support」就是支持UTF8編碼了。日誌

若是Nginx調用的PCRE爲7.9如下的版本,使用 rewrite 「(*UTF8)^/(..)$」 /2個字符文章.html break; 這種形式的重寫,在執行nginx -t檢查時會出現以下的錯誤提示:code

[emerg]: pcre_compile() failed: (*VERB) not recognized in 「(*UTF8)^、……htm

若是Nginx調用的是7.9以上版本的PCRE,可是PCRE安裝時沒打開UTF8的支持開關,則會出現以下的錯誤提示:

nginx: [emerg] pcre_compile() failed: this version of PCRE is not compiled with PCRE_UTF8 support in 「(*UTF8)^/…

解決辦法是安裝最新版本的的PCRE,並打開UTF8支持,方法以下(以當前8.13版的PCRE爲例):
wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.13.tar.gz
tar zxvf pcre-8.13.tar.gz
cd pcre-8.13
./configure --enable-utf8 --enable-unicode-properties
make
make install

而後從新編譯安裝Nginx。 Nginx默認會打開rewrite模塊,並會自動查找系統上已經安裝了的PCRE。 若是Nginx查找不到已經安裝在系統上的PCRE, 或者系統上有多個PCRE, nginx調用了不支持UTF8的、或低版本的PCRE時(我遇到了後一種狀況,並花費了很長的時間解決這個問題,這也是我爲何寫這篇總結文章在這裏給你們分享的緣由。。。),能夠在編譯安裝Nginx時指定PCRE源文件。例如:

wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.13.tar.gz
tar zxvf pcre-8.13.tar.gz
wget http://nginx.org/download/nginx-1.0.8.tar.gz
tar zxvf nginx-1.0.8.tar.gz
cd nginx-1.0.8
./configure 
--with-pcre=../pcre-8.13

注意,若是接着直接make && make install的話, PCRE由於沒有啓用UTF8, nginx將不能支持UTF8重寫, 因此在這一種,我動了一點小手腳:打開./objs/Makefile 文件,找到如下段落:

../pcre-8.13/Makefile: objs/Makefile
cd ../pcre-8.13 
&& if [ -f Makefile ]; then $(MAKE) distclean; fi 
&& CC="$(CC)" CFLAGS="-O2 -fomit-frame-pointer -pipe " 
./configure --disable-shared 

在–disable-shared後加上 –enable-utf8和 –enable-unicode-properties參數, 即變成:
../pcre-8.13/Makefile: objs/Makefile
cd ../pcre-8.13 
&& if [ -f Makefile ]; then $(MAKE) distclean; fi 
&& CC="$(CC)" CFLAGS="-O2 -fomit-frame-pointer -pipe " 
./configure --disable-shared --enable-utf8 --enable-unicode-properties

而後再make, make install。 最後關閉nginx並重啓nginx(這裏不能用nginx -s reload)。這樣nginx就支持中文UTF8編碼的url重寫了。

轉載請註明: 轉自船長日誌, 本文連接地址: http://www.cslog.cn/Content/nginx-pcre-utf8-rewrite/

相關文章
相關標籤/搜索