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

PCRE is not compiled with UTF-8 support

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

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

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

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

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

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

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 stack

顯示“UTF-8 support”就是支持UTF8編碼了。

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

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

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

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

解決辦法是安裝最新版本的的PCRE,並打開UTF8支持,方法如下(以當前8.13版的PCRE爲例):
wgetftp://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源文件。例如:

wgetftp://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 && makeinstall的話, 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 -sreload)。這樣nginx就支持中文UTF8編碼的url重寫了。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章