2012-07-12 42 views
4

我有一個帶有SHIFT_JIS字符集的ASP Classic頁面。在頁面的頭部分的meta標籤是這樣的:如何在Javascript中獲取日文字符的長度?

<meta http-equiv="Content-Type" content="text/html; charset=shift_jis"> 

我的頁面有一個文本框(txtName的)應只允許200個字符。我有一個驗證字符長度的Javascript函數,它在我的提交按鈕的onclick()事件上被調用。

if(document.frmPage.txtName.value.length > 200) { 
    alert("You have exceeded the maximum length of 200."); 
    return false; 
} 

問題是,JavaScript沒有得到在SHIFT_JIS中編碼的日文字符的正確長度。例如,字符測試的SHIFT_JIS長度爲8個字符,但是Javascript只是將其識別爲一個字符,可能是因爲Javascript默認使用的Unicode編碼。在SHIFT_JIS中,像ケ這樣的字符有2或3個字符。

如果我只依賴Javascript提供的長度,長日文字符會通過頁面驗證,並且會嘗試保存在數據庫上,然後由於DB列的最大長度爲200,將會失敗。

我使用的瀏覽器是Internet Explorer。有沒有辦法使用Javascript獲得日文字符的SHIFT_JIS長度?是否有可能使用Javascript從Unicode轉換爲SHIFT_JIS?怎麼樣?

感謝您的幫助!

+0

數據庫字段不是Unicode數據類型嗎?聽起來像你正在陷入一個普通的ASP形式字符entgot難題。 – AnthonyWJones 2012-07-12 15:22:40

+0

請參閱:http://stackoverflow.com/a/920405/17516 – AnthonyWJones 2012-07-12 15:27:07

+0

嗨。我的數據庫有一個帶有排序規則SQL_Latin1_General_CP1_CI_AS的ISO_1字符集。 DB字段的類型爲NVARCHAR(200)。 – 2012-07-13 01:53:40

回答

0

您在字符和字節之間感到困惑。測是一個字符,然而你看它。在UTF-16(這是Javascript使用的)中,它是兩個BYTES。在Shift_JIS中,顯然是8個字節。但在這兩種情況下,它都是一個字符。所以你要做的是將文本長度限制爲200 BYTES。由於Javascript使用的是UTF-16(實際上是UCS-2),所以你可以通過將字符串長度乘以2來得到它的字節長度,但這對Shift_JIS沒有幫助。然後,如果您使用的是Javascript,則應該考慮切換爲Unicode ...

7

例如,字符測試的SHIFT_JIS長度爲8個字符,但Javascript只是將其識別爲一個字符,可能是因爲Unicode編碼的

讓我們清楚:測,U + 6D4B(韓字 '的措施,估計,推測')單個字符。當您將其編碼爲像Shift-JIS這樣的特定編碼時,它可能會變成多個字節

通常,JavaScript不會使編碼表可用,因此您無法找出字符將佔用多少字節。如果你真的需要,你必須攜帶足夠的數據來自己解決問題。例如,如果假定輸入僅包含在Shift-JIS中有效的字符,則此函數將確定需要多少字節,方法是保留所有字符爲單個字節的列表,並假定每個其他字符都需要兩個字節:

function getShiftJISByteLength(s) { 
    return s.replace(/[^\x00-\x80。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン ゙ ゚]/g, 'xx').length; 
} 

但是,也有在移-JIS無8字節序列,並且該字符測不可用在移-JIS的。 (這是一個日本不使用的漢字。)

爲什麼你可能會認爲它構成一個8字節的序列是這樣的:當瀏覽器無法提交表單中的字符時,因爲它不存在於目標字符集中,所以它將其替換爲HTML字符參考:在這種情況下,&#27979;。這是一個有損整數:你不能分辨用戶是按字面輸入還是&#27979;。如果您將提交的內容&#27979;顯示爲,那麼這意味着您忘記對輸出進行HTML編碼,這可能意味着您的應用程序極易受到跨站點腳本的攻擊。

唯一明智的答案是使用UTF-8而不是Shift-JIS。 UTF-8可以愉快地編碼測試或任何其他字符,而不必求助於HTML文件的錯誤引用。如果您需要在數據庫中存儲的編碼的字節長度的限制內容,有偷偷摸摸的黑客,你可以用它來獲得一個字符串的UTF-8字節數:

function getUTF8ByteLength(s) { 
    return unescape(encodeURIComponent(s)).length; 
} 

雖然可能它會更好將本機Unicode字符串存儲在數據庫中,以便長度限制是指實際字符,而不是某些編碼中的字節。

+0

感謝bobince的回答。我試圖在這兩個頁面中使用UTF-8字符集(而不是Shift-JIS),但日文字符不能正確呈現,除非我更改回Shift-JIS字符集。是否可以使用UTF-8在頁面上顯示日文字符? – 2012-07-13 09:56:58

+0

是的,「UTF」編碼可以顯示所有的Unicode字符。首先確保將文檔從文本編輯器保存爲UTF-8而不是Shift-JIS,以糾正靜態頁內文本。然後你需要確保你正在與數據庫安全地交談......不太熟悉經典ASP下的SQL Server,但是[這個問題](http://stackoverflow.com/questions/1856239/classic-asp-how -to-write-unicode-string-data-in-classic-asp)建議設置代碼頁65001(Windows等同於UTF-8)可能會有所幫助。 – bobince 2012-07-13 16:33:01

+0

@markuy:這可能是因爲在您的代碼訪問之前,您的接收頁面已將目前已輸入的數據庫的內容搞亂了,而且沒有將'Response.CodePage'設置爲正確的值(使用@ CODEPAGE也會這樣做)表單域。最終使用NVARCHAR字段,你真的應該切換到UTF-8 _everywhere_它使生活變得如此簡單,一旦你啓動和運行。 – AnthonyWJones 2012-07-14 20:27:11