“被解碼的 URI 不是合法的編碼” 的問題解決

來源:互聯網
上載者:User

同事用prototype.js做ajax應用的時候,因GET請求中含有中文參數導致指令碼運行時總是提示“被解碼的 URI 不是合法的編碼” ,來問我求解。這個問題跟url編碼有關是肯定的了,但具體調試中,卻還是碰了些麻煩,走了點彎路,好在還是順利解決了。同事試了直接傳未編碼的中文參數,不行;又試了escape編碼,不行。我想,換個URLEncode函數應該就OK了吧,沒想到還是不行,錯誤依舊。經過一番alert / prompt / write 之後,疑問被確定在了那個大大的prototype.js檔案上。(這個js架構被比較多的人用,但是我不喜歡用,以前也沒去閱讀它。)出錯的指令碼行最終被定位到一句調用decodeURIComponent方法的地方,找到了就好辦了,我不想去改prototype.js了,乾脆寫個自己的decodeURIComponent覆蓋它。查了文檔知道JScript 5.5 新增的以下4個跟URI編碼解碼相關的函數:
    encodeURI,decodeURI,encodeURIComponent,decodeURIComponent

測試發現,這裡的4個函數(方法)和Java中的類似,都是以Unicode標準進行編碼解碼的,也就是說將漢字視為3位元組進行處理,一個漢字編碼後變為類似的 %hh%hh%hh 的形式,相應的,解碼函數的參數也必須複合編碼結果的格式,二者可逆,否則就會報錯“被解碼的 URI 不是合法的編碼” 。而我們程式中比較常用的GB2312, GBK, UTF-8處理中文都是2位元組的,這是導致問題的根源。例:在編碼為GBK的ASP中,使用Server.URLEncode("中")的結果是%D6%D0,但在用戶端js裡encodeURI("中") encodeURIComponent("中")的結果是%E4%B8%AD ,而如果把%D6%D0傳給decodeURIdecodeURIComponent ,就會報錯“被解碼的 URI 不是合法的編碼” 。

  不想改prototype.js的話,自己寫函數覆蓋上面4個方法的預設實現。下面是我寫的代碼。供參考。

<script language="vbscript">
Function URLEncode(str)
    Dim s,c,a,t
    For i=1 To Len(str)
        c = Mid(str,i,1)
        a = ASC(c)
        If a<0 OR a>255 Then
            t=Hex(a)
            While len(t) mod 2 > 0
                t = "0" & t
            Wend
            For j=1 To len(t)-1 Step 2
                s = s & "%" & Mid(t,j,2)
            Next
        ElseIf a=32 Then
            s = s & "+"
        ElseIf (a>=48 and a<=57) or (a>=65 and a<=90) or (a>=97 and a<=122) Then
            s = s & c
        ElseIf a>0 and a<16 Then
            s = s & "%0" & Hex(a)
        ElseIf a>=16 and a<256 Then
            s = s & "%" & Hex(a)
        Else
            s = s & c
        End If
    Next
    URLEncode = s
End Function

Function URLDecode(input)
    Dim str,code,a(3),b(1)
    str=""
    code=input
    code=Replace(code,"+"," ")
    Const hexstr = "0123456789ABCDEF"
    While len(code)>0
        If InStr(code,"%")>0 Then
            str = str & Mid(code,1,InStr(code,"%")-1)
            code = Mid(code,InStr(code,"%"))
            a(0) = UCase(Mid(code,2,1))
            a(1) = UCase(Mid(code,3,1))
            If a(1)<>"" And InStr(hexstr,a(0))>0 And InStr(hexstr,a(1))>0 Then
                b(0) = Eval("&H" & a(0) & a(1))
                If b(0)>127 And Mid(code,4,1)="%" And len(code)>=6 Then
                    a(2) = UCase(Mid(code,5,1))
                    a(3) = UCase(Mid(code,6,1))
                    If a(3)<>"" And InStr(hexstr,a(2))>0 And InStr(hexstr,a(3))>0 Then
                        b(1) = Eval("&H" & a(2) & a(3))
                        str = str & chr(b(0)*256+b(1))
                        code = Mid(code,7)
                    Else
                        str = str & "%"
                        code = Mid(code,2)
                    End If
                Else
                    str = str & chr(b(0))
                    code = Mid(code,4)
                End If
            Else
                str = str & "%"
                code = Mid(code,2)
            End If
        Else
            str = str & code
            code = ""
        End If
    Wend
    URLDecode = str
End Function
</script>
<script language="javascript">
function encodeURIComponent(code){
    return URLEncode(code);
}
function decodeURIComponent(code){
    return URLDecode(code);
}
function encodeURI(code){
    return URLEncode(code);
}
function decodeURI(code){
    return URLDecode(code);
}
</script>

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.