base64和url編碼注意點

        今日聯調接口,用python2和Java分別調用,一樣的流程結果卻不同,做個記錄。

        該接口是一個http請求,需要將參數進行base64編碼,再組成一個json串,再對json串進行url編碼,將最終的編碼結果進行傳輸。(沒錯就是這麼複雜 -_-!!)

       比對python2和Java代碼組成的最終參數,發現長度和內容不一致。查詢後發現幾個差異點:

1,Java轉base64,內容中增加了許多回車換行符( 即'\r\n')。

查詢原因:

據RFC 822規定,每76個字符,還需要加上一個回車換行

有時就因爲這些換行弄得出了問題,解決辦法就是把回車換行都清除掉

2,python2轉換的參數增加了部分空格,且斜槓'/'沒有轉換,究其原因在於代碼中使用的函數。

import urllib
import base64
import json

fp = open(picture_path, 'rb')
fbuf = fp.read()
fp.close()
picture_base64 = base64.b64encode(fbuf)

data = {"day":"Sunday","activity":"Swimming","picture":picture_base64}
json_str = json.dumps(data)   # dict結構轉化爲json串
param = urllib.quote(json_str) # 進行url編碼

(1)json.dumps轉化,會在鍵值對中加入空格,如上代碼轉換格式後就是:

data = {"day":"Sunday",(空格)"activity":"Swimming",(空格)"picture":picture_base64}

將字符串再處理去掉空格就行了

(2)url編碼函數quote用法

查詢函數定義:

urllib.quote(string [, safe])

將string中的特殊字符轉化爲%xx的格式,其中字母、數字和 '_.-'不會被轉化。可選參數safe後面可以增加不想被轉化的字符,默認值是'/'.

所以在上述代碼中,最終轉化出來的字符串中依然有斜槓,與Java代碼不同。

改爲param = urllib.quote(json_str, safe='') 就OK了

(2.1)擴展

         urllib.quote若想多個字符不想被轉化,可以直接在safe參數添加,

          如不想轉化‘+’和‘=’,只需urllib.quote(string, safe='+=')

 (2.2) 擴展2

         python2中有另一個url編碼函數:urllib.quote_plus。該函數默認會轉化斜槓,但會把空格轉化爲‘+’號

查詢發現,該函數其實也是調用了quote,只是safe傳空,並對空格進行了處理

# quote_plus源碼

def quote_plus(s, safe=''):
    """Quote the query fragment of a URL; replacing ' ' with '+'"""
    if ' ' in s:
        s = quote(s, safe + ' ')
        return s.replace(' ', '+')
    return quote(s, safe)

(2.3) 擴展3:爲何空格有的會轉化爲'+'號

查詢發現,源於兩種不同的標準。

W3C標準規定,當Content-Type爲application/x-www-form-urlencoded時,URL中查詢參數名和參數值中空格要用加號+替代,所以幾乎所有使用該規範的瀏覽器在表單提交後,URL查詢參數中空格都會被編成加號+。

另一份規範(RFC 2396,定義URI)裏, URI裏的保留字符都需轉義成%HH格式(Section 3.4 Query Component),因此空格會被編碼成%20,加號+本身也作爲保留字而被編成%2B,對於某些遵循RFC 2396標準的應用來說,它可能不接受查詢字符串中出現加號+,認爲它是非法字符。

所以一個安全的舉措是URL中統一使用%20來編碼空格字符。

參考鏈接:https://blog.csdn.net/xuebing1995/article/details/80664450

 

一個聯調搞了好久,還是要注重細節。。=_=!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章