哪的資料都不如官方資料權威。現今總算從MSDN中擇出了ASP編碼問題的解。
下面是MSDN中的一段話。
Setting @CODEPAGE explicitly affects literal strings in a single response. Response.CodePage affects dynamic strings in a single response, and Session.CodePage affects dynamic strings in all responses in a session.
這句話解釋清楚了@CODEPAGE,Response.CodePage,Session.CodePage 分別的作用是什麼。
@CODEPAGE作用於所有靜態的字串,例如某文件中的const blogname="我的家"
Response.CodePage,Session.CodePage作用於所有動態輸出的字串,例如<%=blogname%>
這句話很關鍵的是說明了Response.CodePage的作用範圍是a single response,而SXNA中宣告的Session.CodePage的作用範圍是all responses in a session。
再看另外一句話。
If Response.CodePage is not explicitly set in a page, it is implicitly set by Session.CodePage, if sessions are enabled. If sessions are not enabled, Response.CodePage is by pageP. If there is no @CodePage in the page, Response.CodePage is set by the AspCodePage metabase property. If the AspCodePage metabase property is not set, or set to 0, Response.CodePage is codeby the page.
這句話我乍一看,把意思理解成了這樣:在sessions are enabled的時候,如果Response.CodePage沒有聲明,則Response.CodePage會被Session.CodePage賦值。如果sessions are not enabled的時候, 如果@CodePage已聲明,則Response.CodePage會被@CodePage賦值,等等.............
這句話解釋了為什麼從SXNA中出來以後進入一些別的頁面例如oblog,z-blog等等容易出現亂碼,因為其他程式沒有宣告Response.CodePage而恰巧SXNA宣告了Session.CodePage,因此一進入SXNA,Session.CodePage立即被賦值(版本不同,有的版本賦了936有的版本賦了65001),而後進入其他程式的時候Response.CodePage馬上被Session.CodePage賦值,如果這時Response.CodePage與頁面本身編碼不一樣的話,頁面就會出現亂碼。所以進入z-blog出現亂碼的時候我查了當時的Session.CodePage和Response.CodePage都是936,而進入oblog出現亂碼的時候Session.CodePage和Response.CodePage都是65001.就是說要保證葉面不出現亂碼,應該聲明Response.CodePage,否則他就會按照Session.CodePage來解釋網頁(而不是按照@codepage解釋網頁).
如果僅僅按照上面的解釋的話,我實際上是很糊塗的,因為我們都是用的中文操系統,當每一次進入瀏覽器的時候你可以嘗試輸出Session.CodePage,能看到他都是936!為什麼進入Z-blog的時候他不把預設的Session.CodePage的936賦給Response.CodePage呢?反而把@CodePage給了Response.CodePage?什麼情況下Session.CodePage才會賦值給Response.CodePage呢?原文的sessions are enabled該如何理解呢?
也許上面的話應該這樣理解:
在Session.CodePage被任何程式宣告的時候,如果Response.CodePage沒有聲明,則Response.CodePage會被Session.CodePage賦值。如果Session.CodePage沒有被任何程式宣告的時候, 如果@CodePage已聲明,則Response.CodePage會被@CodePage賦值,....,最後的頁面動態內容部分按照Response.CodePage的值解釋。
因為Zblog和Oblog都宣告了@CodePage,所以,使用者剛啟動完機器然後進入瀏覽器瀏覽Zblog和Oblog的時候Response.CodePage會被@CodePage賦值,於是葉面顯示正常。
這句話進一步解釋了產生亂碼的原因
If you set Response.CodePage or Session.CodePage explicitly, do so before sending non-literal strings to the client. If you use literal and non-literal strings in the same page, make sake strings in the same page make) the code page of @CODEPAGE matches the code page of Response.CodePage, or the literal strings are encoded differently from the non-literal strings and display incorrectly.
其中比較有用的一句話是說如果Response.CodePage和@CODEPAGE不一樣的話會產生亂碼。也就是說當Z-blog的@CODEPAGE=65001而Z-blog的Response.CodePage被Session.CodePage賦為936的時候就會出現亂碼,oblog反之亦然。
我不知道上面說了這麼多解釋清楚沒有-_-||
下面解釋一下為什麼SXNA有時會把Session.CodePage賦為936,我有一個版本是這樣寫的:
<% OriginalCodePage=Session.CodePage %>
.. .....
<% Session.CodePage=OriginalCodePage %>
當使用者進入瀏覽器的時候Session.CodePage預設為936,這個時候的預設936不是程式宣告的,因此不會賦給Response.CodePage,當進入SXNA的時候,Session.CodePage被上面那段程式碼一折騰就變成了程式宣告的Session.CodePage=936,因此再進入Zblog的時候就把936給了Response.CodePage。
至此,全部原因已經分析清楚了。
因此說,保證asp葉面一定不會出現亂碼的程式碼應該是這樣的:(假定是UTF-8的葉子)
<%@ CODEPAGE=65001 %>
<% Response.CodePage=65001%>
<% Response.Charset ="UTF-8" %>
進一步說明為什麼要加Response.Charset,因為MSDN說
要加...呵呵If the code page is set in a page, then Response.Charset should also be set.
,檔案的編碼格式應該與@CODEPAGE一樣: The
file format of a Web page must be the same as the @CODEPAGE used in the page.
這就是為什麼zblog,pjblog等一些程式要吧檔案存成UTF8編碼格式的原因.
綜上,如果所有的程式都宣告了Response.CodePage就不會被Session.CodePage幹擾而出現亂碼了。所以Session.CodePage還是不能輕易用的!
參考文章:
url=/library/en-us/iissdk/html/268f1db1-9a36-4591-956b-d7269aeadcb0.asp