在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(r'https?://([^/?]+)', 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响应的更多相关文章

  1. Flask中的Templates

    1.什么是模板 模板 , 在Flask 中就是允许响应给用户看的网页 在模板中,允许包含"占位变量"来表示动态的内容 模板最终也会被解析成字符串再响应给客户端,这一过程通常称为&q ...

  2. Flask框架 请求与响应 & 模板语法

    目录 Flask框架 请求与响应 & 模板语法 简单了解Flask框架 Flask 框架 与 Django 框架对比 简单使用Flask提供服务 Flask 中的 Response(响应) F ...

  3. Flask Response响应(flask中设置响应信息的方法,返回json数据的方法)

    设置响应信息的方法 1.  返回自定义的响应头,有两种方式: (1)  第一种是:视图函数return的时候,使用元组,返回自定义的信息 返回的时候的状态码可以自定义信息:"状态码   自定 ...

  4. Flask 中的 5种返回值

    1.Flask中的HTTPResponse 在Flask 中的HttpResponse 在我们看来其实就是直接返回字符串 2.Flask中的Redirect 每当访问"/redi" ...

  5. 记录python接口自动化测试--根据excel中的期望输出是否存在请求返回的响应来判断用例是否执行成功(第八目)

    1.首先在excel中的expectValue列填好预期结果值 这里判断接口成功的依据是预期结果值是否存在于接口返回的数据中. 首先,要知道在之前封装的get/post请求方法中返回的是‘str’,也 ...

  6. Flask 中字典数据返回(jsonify)

    不多说,直接上代码,flask中的字典数据的处理: from flask import Flask, jsonify app = Flask(__name__, static_folder=" ...

  7. 服务器文档下载zip格式 SQL Server SQL分页查询 C#过滤html标签 EF 延时加载与死锁 在JS方法中返回多个值的三种方法(转载) IEnumerable,ICollection,IList接口问题 不吹不擂,你想要的Python面试都在这里了【315+道题】 基于mvc三层架构和ajax技术实现最简单的文件上传 事件管理

    服务器文档下载zip格式   刚好这次项目中遇到了这个东西,就来弄一下,挺简单的,但是前台调用的时候弄错了,浪费了大半天的时间,本人也是菜鸟一枚.开始吧.(MVC的) @using Rattan.Co ...

  8. Flask中current_app和g对象

      Flask零基础到项目实战(七)请求方法.g对象和钩子函数 一.get方法 二.post方法 post请求在模板中要注意几点: input标签中,要写name来标识这个value的key,方便后台 ...

  9. Python框架学习之Flask中的Jinja2模板

    前面也提到过在Flask中最核心的两个组件是Werkzeug和Jinja2模板.其中Werkzeug在前一节已经详细说明了.现在这一节主要是来谈谈Jinja2模板. 一.为什么需要引入模板: 在进行软 ...

随机推荐

  1. 【learning】洲阁筛

    问题描述 快速求素数处点值比较好求的积性函数前缀和 大致过程 Step1.求出一定范围内的素数处点值之和(\(g\)) Step2.利用上面的\(g\)求出一个\(f\)然后用\(f\)求出前缀和 具 ...

  2. Python2和Python3共存安装

    记录下: 先下载Python2.7.6,安装完成,不要添加到path中: 再下载Python3.4.3,安装,不要添加到path中. 进入 Python2: py -2 进入Python3: py - ...

  3. Android 基于身份证号的自定义键盘

    上图上代码 public class MainActivity extends AppCompatActivity { EditText writebankcard_mobileedit; Custo ...

  4. vue使用插件 使用库

    用插件1.引用import VueResource from 'vue-resource'2.使用Vue.use(VueResource); 用库(bootstrap alertify )1.引入: ...

  5. 前端PHP入门-034-Session技术-掌握级别

    而Session是通过将数据保存在服务器端来实现保持连接的.我们通过一个例子来了解session的机制. 我们去饮料店买饮料,下单以后服务员会给我们一个号码牌,然后你走到一旁,服务员并不认识你是谁,如 ...

  6. Final类和Final方法

    终止继承 Final类 当关键字final用来修饰类时,其含义是该类不能在派生子类.换句话说,任何其他类都不能继承用final修饰的类,即使该类的访问限制为public类型,也不能被继承:否则,将编译 ...

  7. JVM调优总结(4):分代垃圾回收

    为什么要分代 分代的垃圾回收策略,是基于这样一个事实:不同的对象的生命周期是不一样的.因此,不同生命周期的对象可以采取不同的收集方式,以便提高回收效率. 在Java程序运行的过程中,会产生大量的对象, ...

  8. 重构改善既有代码设计--重构手法08:Replace Method with Method Object (以函数对象取代函数)

    你有一个大型函数,其中对局部变量的使用,使你无法釆用 Extract Method. 将这个函数放进一个单独对象中,如此一来局部变量就成了对象内的值域(field) 然后你可以在同一个对象中将这个大型 ...

  9. CSS属性的私有前缀

    在CSS属性能中,我们常常能看到-webkit-,-moz-之类的前缀,这种就叫做浏览器私有前缀,是浏览器对于新CSS属性的一个提前支持.-webkit-是webkit内核的,-moz-是Firefo ...

  10. 云风pbc源码alloc.c

    #include <stdlib.h> #include <stdio.h> // 用于统计内存的申请和释放次数匹配 ; void * _pbcM_malloc(size_t ...