1. 程式人生 > >jmeter錄製帶中文的get請求回放會報錯如何解決

jmeter錄製帶中文的get請求回放會報錯如何解決

在一次專案中,用jmeter代理方式錄製(通過Chrome谷歌瀏覽器)完指令碼,然後在回放中,發現帶漢字的get請求會報錯,具體報錯原因如下所示:

原因是本次系統頁面用谷歌瀏覽器代理錄製的指令碼中(另外網上也提到IE和Firefox對於中文路徑都是以UTF-8編碼並帶%號傳送,IE和Firefox對於中文查詢條件都是以GB2312編碼傳送,但是Firefox帶%號,IE不帶;而對於GET和POST傳送的請求,編碼是由頁面編碼決定的),發現漢字是Unicode編碼而不是以基於UTF-8形式的URL編碼呈現,但是由Jmeter傳送的URL請求引數,必須是嚴格按照UTF-8的URL編碼形式,否則就會引起不識別的錯誤。

解決辦法有以下不同方式:

一、將漢字用URL編碼工具替換成標準的URL編碼格式

二、整個JSON內容不進行URL編碼(保留未編碼的標準漢字形式),並輸入(如果抓包或錄製的是已經被編碼的串,可以通過網上的URL編碼/解碼工具進行解碼,還原成初始狀態)到Parameters值中,然後勾選編碼選項(這樣就交由jmeter來完成編碼)


URL編碼/解碼可以用以下的線上工具

http://tool.chinaz.com/tools/urlencode.aspx

三、對於通過BODY傳送的中文內容可以用Jmeter自帶函式實現轉碼

${__javaScript(encodeURIComponent('${token}'))}

${__urlencode('${token}'))}

我們藉助這兩個函式來實現,這樣在變數或者csv引數檔案中填寫中文,然後在請求中呼叫這兩個函式來實現編碼,如圖,這樣就解決了URL編碼問題


補充說明(如何在源端規範編碼):

不同的作業系統、不同的瀏覽器、不同的網頁字符集,將導致完全不同的編碼結果。如果程式設計師要把每一種結果都考慮進去,是不是太恐怖了?有沒有辦法,能夠保證客戶端只用一種編碼方法向伺服器發出請求?
回答是有的,就是使用Javascript先對URL編碼,然後再向伺服器提交,不要給瀏覽器插手的機會。因為Javascript的輸出總是一致 的,所以就保證了伺服器得到的資料是格式統一的。

跟大家推薦一個學習資料分享群:175317069

一、Javascript函式:escape()
Javascript語言用於編碼的函式,一共有三個,最古老的一個就是escape()。雖然這個函式現在已經不提倡使用了,但是由於歷史原因, 很多地方還在使用它,所以有必要先從它講起。
實際上,escape()不能直接用於URL編碼,它的真正作用是返回一個字元的Unicode編碼值。比如“春節”的返回結果 是%u6625%u8282,也就是說在Unicode字符集中,“春”是第6625個(十六進位制)字元,“節”是第8282個(十六進位制)字元。

它的具體規則是,除了ASCII字母、數字、標點符號“@ * _ + - . /”以外,對其他所有字元進行編碼。在/u0000到/u00ff之間的符號被轉成%xx的形式,其餘符號被轉成%uxxxx的形式。對應的解碼函式是 unescape()。
所以,“Hello World”的escape()編碼就是“Hello%20World”。因為空格的Unicode值是20(十六進位制)。

還有兩個地方需要注意。
首先,無論網頁的原始編碼是什麼,一旦被Javascript編碼,就都變為unicode字元。也就是說,Javascipt函式的輸入和輸出, 預設都是Unicode字元。這一點對下面兩個函式也適用。

其次,escape()不對“+”編碼。但是我們知道,網頁在提交表單的時候,如果有空格,則會被轉化為+字元。伺服器處理資料的時候,會把+號處 理成空格。所以,使用的時候要小心。
二、Javascript函式:encodeURI()
encodeURI()是Javascript中真正用來對URL編碼的函式。
它著眼於對整個URL進行編碼,因此除了常見的符號以外,對其他一些在網址中有特殊含義的符號“; / ? : @ & = + $ , #”,也不進行編碼。編碼後,它輸出符號的utf-8形式,並且在每個位元組前加上%。

它對應的解碼函式是decodeURI()。

需要注意的是,它不對單引號'編碼。

三、Javascript函式:encodeURIComponent()
最後一個Javascript編碼函式是encodeURIComponent()。與encodeURI()的區別是,它用於對URL的組成部分 進行個別編碼,而不用於對整個URL進行編碼。
因此,“; / ? : @ & = + $ , #”,這些在encodeURI()中不被編碼的符號,在encodeURIComponent()中統統會被編碼。至於具體的編碼方法,兩者是一樣。

它對應的解碼函式是decodeURIComponent()。
PS1 :
網頁裡的form編碼其實不完全取決於網頁編碼,form標記中有一個accept-charset屬性,在非ie瀏覽器種,如果將其賦值(比如 accept-charset="UTF-8"),則表單會按照這個值表示的編碼方式進行提交。
在ie下,我的相容解決辦法是:
form1.onsubmit=function(){
document.charset=this.getAttribute('accept-charset');
}

四、中文編碼轉換樣例       

  /** 中文字串轉UTF-8與GBK碼示例   
             */  
   public static void tttt() throws Exception {  
        String old = "手機銀行";  
          
        //中文轉換成UTF-8編碼(16進位制字串)  
        StringBuffer utf8Str = new StringBuffer();  
        byte[] utf8Decode = old.getBytes("utf-8");  
        for (byte b : utf8Decode) {  
            utf8Str.append(Integer.toHexString(b & 0xFF));  
        }  
//      utf8Str.toString()=====e6898be69cbae993b6e8a18c  
//      System.out.println("UTF-8字串e6898be69cbae993b6e8a18c轉換成中文值======" + new String(utf8Decode, "utf-8"));//-------手機銀行  
          
          
        //中文轉換成GBK碼(16進位制字串)  
        StringBuffer gbkStr = new StringBuffer();  
        byte[] gbkDecode = old.getBytes("gbk");  
        for (byte b : gbkDecode) {  
            gbkStr.append(Integer.toHexString(b & 0xFF));  
        }  
//      gbkStr.toString()=====cad6bbfad2f8d0d0  
//      System.out.println("GBK字串cad6bbfad2f8d0d0轉換成中文值======" + new String(gbkDecode, "gbk"));//----------手機銀行  
          
          
        //16進位制字串轉換成中文  
        byte[] bb = HexString2Bytes(gbkStr.toString());  
        bb = HexString2Bytes("CAD6BBFAD2F8D0D0000000000000000000000000");  
        byte[] cc = hexToByte("CAD6BBFAD2F8D0D0000000000000000000000000", 20);  
        String aa = new String(bb, "gbk");  
        System.out.println("aa====" + aa);  
    } 

結語:

跟大家推薦一個學習資料分享群:175317069,裡面大牛已經為我們整理好了許多的學習資料,有自動化,介面,效能等等的學習資料!人生是一個逆水行舟的過程,不進則退,咱們一起加油吧!