1. 程式人生 > >在flask中返回requests響應

在flask中返回requests響應

cnblogs led form status redirect 壓縮 rom out 自動跳轉

  在flask服務端,有時候需要使用requests請求其他url,並將響應返回回去。查閱了flask文檔,About Responses,可以直接構造響應結果進行返回。

  If a tuple is returned the items in the tuple can provide extra information. Such tuples have to be in the form (response, status, headers) or (response, headers) where at least one item has to be in the tuple. The status value will override the status code and headers can be a list or dictionary of additional header values.

  

_headers = {
    Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,
    Accept-Encoding:gzip, deflate, br,
    Accept-Language:zh-CN,zh;q=0.8,
    User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36
} def proxy(url, try_times=0): headers = dict(_headers) headers[Host] = re.match(rhttps?://([^/?]+), url).group(1) response = requests.get(url, headers=headers, timeout=5, allow_redirects=False) #禁用自動跳轉,因為跳轉後Host可能會變,需要重新計算 if 300 < response.status_code < 400 and try_times < 3: url
= response.headers.get(Location) if url.startswith(/): return redirect(url, code=response.status_code) #相對地址,特殊處理 try_times += 1 return proxy(url, try_times) return response.content, response.status_code, response.headers.items()

  這段代碼在大部分情況下都運行良好。flask服務端顯示相應正常,瀏覽器也看到有返回相應,偶爾瀏覽器出現ERR_CONTENT_DECODING_FAILED錯誤。看英文錯誤應該是,內容解碼錯誤。

看了下requests的相應頭中有,Content-Encoding: gzip,顯示了網頁內容進過gzip壓縮。而requests會對部分壓縮的內容進行解碼:The gzip and deflate transfer-encodings are automatically decoded for you.

  知道原因了,解決辦法也很容易。1、刪除相應頭中的Content-Encoding,因為經過requests之後,返回給瀏覽器的已經不是壓縮的內容了。2、重新計算Content-Length

def make_response(response):
    headers = dict(response.headers)
    content_encoding = headers.get(Content-Encoding)
    if content_encoding == gzip or content_encoding == deflate:
        del headers[Content-Encoding]
    if headers.get(Transfer-Encoding):
        del headers[Transfer-Encoding]
    if headers.get(Accept-Ranges):
        del headers[Accept-Ranges]
    headers[Content-Length] = len(response.content)
    return response.content, response.status_code, headers.items()

在flask中返回requests響應