【求助】如何讓apache支援utf-8編碼的檔案請求?



贊助商連結


頁 : [1] 2 3

b90220208
2005-04-11, 06:08 PM
如題:
如何讓apache支援utf-8編碼的檔案請求?
例如client請求perl檔案時,apache需要去讀取shebang line(即該檔的第一行),才曉得要去哪找perl處理程式.

我自己試過若將perl以xp預設的ANSI編碼存檔則沒問題.
而若以utf-8存檔,當用browser瀏覽時會出現如下錯誤訊息:
======================================================
Internal Server Error
The server encountered an internal error or misconfiguration and was unable to complete your request.
Please contact the server administrator, [no address given] and inform them of the time the error occurred, and anything you might have done that may have caused the error.

More information about this error may be available in the server error log.


======================================================
以下為apache的log file紀錄:
----------------------------
[Sat Apr 09 15:18:19 2005] [error] [client 203.204.136.209] e:/appserv2-5-1/www/hello4.pl is not executable; ensure interpreted scripts have "#!" first line

[Sat Apr 09 15:18:19 2005] [error] [client 203.204.136.209] (2)No such file or directory: couldn't spawn child process: e:/appserv2-5-1/www/hello4.pl

很顯然,APACHE找不到以#!為開頭的shebang line,
問題是我的perl檔案可是有在第一行明確寫上#!e:\perl\bin\perl.exe,
所以我懷疑是apache看不懂以utf-8編碼的perl檔案,才會導致此一錯誤訊息...

贊助商連結


b90220208
2005-04-11, 09:14 PM
我查了一下資料,大致了解win32系統下的文檔習慣以特定字元 (慣稱為 BOM: Byte-Order Mark) 開頭,來表示該文檔是採 BE 或 LE 方式編碼.
大概是APACHE在接收到perl文件請求時,假如httpd.conf中的定義是交由由shebang line明定之路徑下的perl解譯器處理,那麼apache就得去讀取perl文件的第一行,這時問題就出現了,因為apache看不懂BOM這一特殊用途字元,且剛好BOM又位於文件第一行之開端,所以才會導致client browser接收到"伺服器無法處理的內部問題等錯誤訊息..."

Q1:
只是我還是不了解,ANSI編碼儲存網頁文件時不也有BOM的情形嗎?
為何用ANSI就沒事,UTF-8就有事??

Q2:
為何APACHE會看不懂BOM字元呢?
(難道它不支援UTF-8嗎?)

Q3:
順便請教,
一般編寫網頁檔案需要注重編碼的選擇嗎?
若想讓文件更有可攜性,例如移轉於linux與windows之間,
是否以utf-8編碼網頁相關文件較好呢?

mus000
2005-04-12, 01:11 AM
其實 apache2 已經支援 UTF-8 了。
你可以試試 htm 檔,或是用 php 去試也行,都是 ok 的。

唯一有問題的是 apache2 + perl。

perl 在 5.8.x 後的版本也支援 utf-8 ,也可以用命令列模式正常執行 utf8內容的檔。

所以 .... 應該是 apache2 跟 perl 的相容性出問題吧。

b90220208
2005-04-13, 03:19 PM
:D 我大概有頭緒知道怎麼問了,由於perl在5.6版以後就已支援utf-8,所以其compiler是ok的.

Q1:
問題只在apache這個本以unix為主的套件看不懂win32系統特有的BOM,所以才會有無法解讀shebang line的問題,當然也就找不到perl compiler來處理client請求的perl文件.但若以此認知,那麼改成ANSI編碼存檔時難道就無BOM的問題嗎?
因為Win32系統習慣會對文檔加上BOM字元來區分文件屬於BE或LE...

--> 此疑問我已找到相關解釋: 主要是BOM是為多位元組而設計的,而在 ANSI (ASCII)編碼中,一個位元組等於一個字元,所以不必用 BOM.


[補充]: 關於 Byte-Order Mark,這是我找到的解釋:
-------------------------------------------------------------------------------------------
先說明一下什麼是 Byte-Order:在一些平台上,是把代表數值較大的 byte 放在前面,這稱為 Big Endian (BE) 的系統;有些平台則相反,是把代表數值較小的 byte 放在前面,稱為 Little Endian (LE) 的系統。

若採 LE 方式編碼,BOM 會表示為 0xFF 0xFE,而在 Unicode 的定義中是不存在 U+FFFE 這個字元的.

若採 BE 方式編碼,BOM 會表示為 0xFE 0xFF,而 U+FEFF 剛好是在 Unicode 中的有效字元,代表的是一個不佔空間的 space 符號,所以即使沒被解釋為 BOM,也不會對閱覽者產生錯誤的訊息.
-------------------------------------------------------------------------------------------

Q2:
因此,會不會是出在utf-8本身,
由於它沒有BOM的支援,所以當我存檔時,windows的記事本程式會為文件標上 U+FEFF 字元.
而當apache收到perl的文件請求進而去讀取shebang line時(這點我不確定正確與否,因為在其他討論區看過有人說什麼apache不會去讀文件只會傳送文件...的論調,so,若您清楚的話還請您為我釐清,在此我先假設apache會讀取請求的文件),所以假設文件是用ANSI編碼,那麼就無BOM字元的問題,
但若文件是以UTF-8存檔,即便apache有支援utf-8,但若讀到BOM時,它不是當成space就是認為無意義...而不管何者發生,就如前所說,因為在 Unix 系統有所謂的 magic word,即以檔案的前兩個 byte 來辨識該檔的性質.例如 perl script 檔的shebang line,開頭必定是 "#!".因此原就是以 unix 為主的 apache 也就無法判讀....因此client 端的 browser 才會收到"伺服器的內部錯誤..."訊息.


Q3:
關於:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
我當然有寫上,也正因如此browser還會把中文字顯示成亂碼我才搞不懂??

p.s 不好意思,再次說明我的情形:
我將原先以ANSI存檔的網頁文件重新以記事本或者EmEditor存成utf-8,使用後者時我還選擇不加上BOM這一特殊用途字元,且也以CR+LF的windows預設換行的方式重新存檔.....當然我也有在browser工具鈕的"檢視"中的"編碼"選擇"自動選取".....god! 快來救救我啊!


Q4:
最後就是ANSI與BIG5有什麼不同?
You know,關於
<meta http-equiv="Content-Type" content="text/html; charset=big5">
為何不能寫成
<meta http-equiv="Content-Type" content="text/html; charset=ansi">
以往編寫網頁文件時都是以ansi存檔,即表示其也支援"中","英"字元符號不是嗎?


****************************************************
為免於我的解讀有誤,以下附上我所查詢的BOM等資訊來源:
http://mfhsieh.blogspot.com/2005/03/pda-zaurus-c760-35-utf-8-and-bom.html
:) :) :)

mus000
2005-04-13, 07:38 PM
果然是 BOM 被解讀錯誤的問題。之前觀念有誤修正了。感謝。

剛剛試著用 emeditor 把測試用的 .pl 檔另存成不含 BOM 的檔,在 apache2上執行就ok 了。

至於 apache2 怎麼丟資訊給 perl 的,這部份不清楚。



<meta http-equiv="Content-Type" content="text/html; charset=ansi">
以往編寫網頁文件時都是以ansi存檔,即表示其也支援"中","英"字元符號不是嗎?

沒那個意思吧。
那一行是給瀏覽器看的,當瀏覽器看到 charset=big5 時,會自動將編碼切換到big5編碼來顯示。如果設定成 utf-8,就表示網頁要以utf-8編碼來顯示。
ansi? 不記得有人這樣子用耶。

至於中文亂碼,除了檢查上述給瀏覽器看的設定之外,還可以檢查以下幾個地方:

1. 網頁輸出前使用 print header (-charset => 'utf-8')';
這樣會以 utf-8 編碼輸出網頁。

2. 在網頁開頭加上
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

3. 修改 httpd.conf 的預設輸出,
#AddDefaultCharset ISO-8859-1
沒有預設值,你可以將它改成
AddDefaultCharset UTF-8

b90220208
2005-04-13, 10:53 PM
請教關於您說的在apache httpd.conf加入AddDefaultCharset utf-8 這一動作,

在網頁文件中加下面這行
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
這兩個動作是否為同一目的,若是,是否任作其一即可?

不論是在httpd.conf還是<meta>的 charset設定,請教有大小寫之差嗎?

mus000
2005-04-13, 11:08 PM
任一即可。
加在 httpd.conf 會對全部網頁都有作用,但是可能會去影響到 script 輸出時的彈性。
大小寫是沒差的。
比如google 的寫法是:
<meta http-equiv="content-type" content="text/html; charset=UTF-8">

b90220208
2005-04-14, 06:57 PM
一般用windows的記事本存寫好的網頁文件時都會有個編碼選擇:
utf-8
unicode
ansi...

Q1:
我想問的是,其 ANSI 指的是 BIG5 還是單純的 ASCII code呢?
(由於其能儲存中文字元所以我會猜是BIG5...不知對不對?)

我會這樣問是因為:
一個是雙位元組,一個則是單位元組,
前面前輩有提到 BOM 是WIN32為多位元組編碼系統設計的,既如此,
當我的 perl script 以 ANSI 存檔時為何不會有 BOM 的問題呢?

Q2:
若Q1的答案是BIG5,
那麼例如我由XOOPS,MT BLOG等網站抓下來的檔案,我想若非以UTF-8就是以ANSI(ASCII)為編碼的吧.
既如此,為何當我以記事本開啟這些文件時都能正常顯示呢?

mus000
2005-04-14, 08:20 PM
有點小複雜了說。
ANSI 是美國國家標準局,他們制定了 ASCII 碼。後來各國由 ASCII 碼為基礎又各自發展了相容於 ASCII 的各國編碼。如 BIG5,GB,EUC,JIS....等等。
統稱 ANSI 碼。

一般要儲存成 ANSI 碼時,如果沒特別詢問,就是以作業系統當時預設的語系來處理。繁體中文作業系統,自然是用 BIG5 碼當預設值來儲存。
而像 emeditor 這類可以處理各種編碼的文書軟體,就可讓使用者自行選擇你要存成哪一種編碼。但是不同編碼會造成些許不同差異。

而BOM,請回頭看看您找到的資訊,BOM 只存在 Unicode 檔案中,ANSI 檔案中並沒有BOM存在的。
而BOM主要用意,是要區分 Unicode 檔內容,是以哪種格式儲存的,比如 BE、LE、UTF-8、UTF-7 的區別。當你選擇其中一種儲存時,這個檔就是 Unicode文件了。而一般 BOM 資訊也在這時就儲存了。

ANSI 沒有 BOM,自然不用去理 BOM 那些問題。
通常要處理 ANSI 的編碼,都是得使用者或程式設計師自行考量。當你確定內容資料是 BIG5 中文時,就下指令讓 perl 以 big5 編碼來處理資料。
有時還得寫額外的處理方式。
不然就會常看到『許功蓋』亂碼的問題一一出現,甚至出現處理錯誤的結果。

再來關於記事本。
記事本是 windows 內建的軟體,它是用什麼編碼來打開文件的?
1. 當文件存在 BOM 資訊時,解讀 BOM 資訊,以 Unicode 內容打開。
2. 當文件是 ANSI 時,就以系統預設編碼來處理。繁中作業系統就是 BIG5。
3. 當文件是任一種 Unicode 格式,但不含 BOM 時,記事本會?? (不清楚,可能還是會正常解讀出內容吧)

而記事本在儲存時,只有確定是 Unicode 檔案時,才會儲存BOM資訊。

而對於有需要刪除 BOM 資訊的人,只能借著其它軟體,如 emEditor。

但是,沒有了BOM資訊的 Unicode 檔,真的是好事嗎?

b90220208
2005-04-15, 09:36 PM
Thanks a lot! :circle:

所以,假若以僅支援ASCII Code的文書程式去解讀一份BIG5編碼的文件時,
結果就是只有英文,數字能正常顯示,而中文則顯示成亂碼...對嗎?

ex:
(以下為big5編碼的文件內容)
AB中文

(以下則為該文件的ENCODING)
0x410x420xA4A40xA4E5

(以下則為該文件實際上的MACHINE CODE~機械碼)
01000001
01000010
1010010010100100
1010010011100101

而若我以只支援ASCII的程式開啟該文件時,程式會根據二進制的MACHINE CODE換算成十進制以符合ASCII的編碼對照.所以該文件內容ENCODING便成了如下模樣:
65664214842213

-> 根據ASCII只解讀的出A與B其餘則變成亂碼...這樣想對嗎?

--------
請問如果php網頁以utf-8存檔,但mysql database卻使用BIG5.
此前提下browser的畫面只要文字是由database調出來的且為中文時就會變亂碼,
但若非從database調出,而是原先就寫在php file的中文字就沒問題,這樣是否表示在PHP調資料時還要加上轉碼的函式,如此該怎麼作呢?

--------
以下網址則又有另一個問題,
http://study-note.blogdns.org:8080/blog/mt/
browser以utf-8顯示網頁都沒問題,但若點選檢視原始檔時,記事本就無法正確顯示中文字...
不知這又是何原因啊??

--------
最後就是關於您提到的:
"BOM主要用意,是要區分 Unicode 檔內容,是以哪種格式儲存的,比如 BE、LE、UTF-8、UTF-7 的區別。"

我有點混亂,因為我查到的資訊只說到BOM是WINDOWS系統用來分辨UNICODE文件屬於BE(U+FEFF)或者LE(U+FFFE)的,而UTF-8文件可能包含單位元組,雙位元組,三位元組.
也因為每個字元不見得剛好是 2 個 byte,所以不管是以 LE 或是 BE 為主的系統上,UTF-8 文檔大都採 BE 方式編碼.