Flask 跨域问题

一、什么是跨域

跨域是指:浏览器A服务器B获取的静态资源,包括Html、Css、Js,然后在Js中通过Ajax访问C服务器的静态资源或请求。即:浏览器A从B服务器拿的资源,资源中想访问服务器C的资源。

同源策略是指:浏览器A服务器B获取的静态资源,包括Html、Css、Js,为了用户安全,浏览器加了限制,其中的Js通过Ajax只能访问B服务器的静态资源或请求。即:浏览器A从哪拿的资源,那资源中就只能访问哪。

同源是指:同一个请求协议(如:Http或Https)、同一个Ip、同一个端口,3个全部相同,即为同源。

跨域的处理

W3C组织制定了一个Cross-Origin Resource Sharing规范,简写为Cors,现在这个规范已经被大多数浏览器支持,Cors 专门用来处理跨域的需求。

Cors需要在后端应用进行配置,因此,是一种跨域的后端处理方式,这么做也容易理解,一个你不认识的源来访问你的应用,自然需要应用进行授权。除了后端处理方式,也有前端的解决方案,如:JSONP,这里我们主要讲解Flask后端配置方案.

跨域的分类

跨域分为以下3种

名称英文名说明
简单请求Simple Request发起的Http请求符合:
1.无自定义请求头,只有Accept、Accept-Language、Content-Language、Last-Event-ID
2.请求动词为GET、HEAD或POST之一
3.动词为POST时,Content-Type是application/x-www-form-urlencoded,multipart/form-data或text/plain之一
复杂请求Preflighted Request发起的Http请求符合其中之一:
1.包含了自定义请求头
2.请求动词不是GET、HEAD或POST
3.动词是POST时, Content-Type不是application/x-www-form-urlencoded,multipart/form-data或text/plain。 即:简单请求的相反
凭证请求Requests with Credential发起的Http请求中带有凭证

简单请求

简单请求的发送从代码上来看和普通的XHR没太大区别,但是HTTP头当中要求总是包含一个域(Origin)的信息。该域包含协议名、地址以及一个可选的端口。不过这一项实际上由浏览器代为发送,并不是开发者代码可以触及到的。

简单请求的部分响应头如下:

  1. Access-Control-Allow-Origin(必含)。不填,请求按失败处理。该项控制数据的可见范围,如果希望数据对任何人都可见,可以填写"*"。
  2. Access-Control-Allow-Credentials(可选)。该项标志着请求当中是否包含cookies信息,只有一个可选值:true(必为小写)。如果不包含cookies,请略去该项,而不是填写false。这一项与XmlHttpRequest2对象当中的withCredentials属性应保持一致,即withCredentials为true时该项也为true;withCredentials为false时,省略该项不写。反之则导致请求失败。
  3. Access-Control-Expose-Headers(可选) – 该项确定XmlHttpRequest2对象当中getResponseHeader()方法所能获得的额外信息。通常情况下,getResponseHeader()方法只能获得如下的信息:(当你需要访问额外的信息时,就需要在这一项当中填写并以逗号进行分隔)
    1. Cache-Control
    2. Content-Language
    3. Content-Type
    4. Expires
    5. Last-Modified
    6. Pragma

如果仅仅是简单请求,那么即便不用CORS也没有什么大不了,但CORS的复杂请求就令CORS显得更加有用了。简单来说,任何不满足上述简单请求要求的请求,都属于复杂请求。比如说你需要发送PUT、DELETE等HTTP动作,或者发送Content-Type: application/json的内容。

复杂请求

复杂请求先发送一种"预请求",此时作为服务端,也需要返回"预回应"作为响应。预请求实际上是对服务端的一种权限请求,只有当预请求成功返回,实际请求才开始执行。预请求以OPTIONS形式发送,当中同样包含域,并且还包含了两项CORS特有的内容:

  1. Access-Control-Request-Method – 该项内容是实际请求的种类,可以是GET、POST之类的简单请求,也可以是PUT、DELETE等等。
  2. Access-Control-Request-Headers – 该项是一个以逗号分隔的列表,当中是复杂请求所使用的头部。

显而易见,这个预请求实际上就是在为之后的实际请求发送一个权限请求,在预回应返回的内容当中,服务端应当对这两项进行回复,以让浏览器确定请求是否能够成功完成。复杂请求的部分响应头及解释如下:

  1. Access-Control-Allow-Origin(必含) – 和简单请求一样的,必须包含一个域。
  2. Access-Control-Allow-Methods(必含) – 这是对预请求当中Access-Control-Request-Method的回复,这一回复将是一个以逗号分隔的列表。尽管客户端或许只请求某一方法,但服务端仍然可以返回所有允许的方法,以便客户端将其缓存。
  3. Access-Control-Allow-Headers(当预请求中包含Access-Control-Request-Headers时必须包含) – 这是对预请求当中Access-Control-Request-Headers的回复,和上面一样是以逗号分隔的列表,可以返回所有支持的头部。这里在实际使用中有遇到,所有支持的头部一时可能不能完全写出来,而又不想在这一层做过多的判断,没关系,事实上通过request的header可以直接取到Access-Control-Request-Headers,直接把对应的value设置到Access-Control-Allow-Headers即可。
  4. Access-Control-Allow-Credentials(可选) – 和简单请求当中作用相同。
  5. Access-Control-Max-Age(可选) – 以秒为单位的缓存时间。预请求的的发送并非免费午餐,允许时应当尽可能缓存。

一旦预回应如期而至,所请求的权限也都已满足,则实际请求开始发送。

目前大部分Modern浏览器已经支持完整的CORS,但IE直到IE11才完美支持,所以对于PC网站,还是建议采用其他解决方案,如果仅仅是移动端网站,大可放心使用。

Flask配置跨域

flask 配置cors 有两种方式,一种使用自带的cors,一种自定义返回头

第一种,自定义返回头

@app.after_request
def af_request(resp):     """#请求钩子,在所有的请求发生后执行,加入headers。:param resp::return:"""resp = make_response(resp)resp.headers['Access-Control-Allow-Origin'] = '*'resp.headers['Access-Control-Allow-Methods'] = 'GET,POST'resp.headers['Access-Control-Allow-Headers'] = 'x-requested-with,content-type'return resp

第二种,使用cors

Flask配Cors跨域,使用Flask-CORS包,详细文档,参见: https://flask-cors.readthedocs.io/en/latest/

flask-cors 也提供了两种方式:

方式

范围

说明

@cross_origin装饰器

配置单个路由

适用于配置特定的API接口

CORS函数

配置全局API接口

适用于全局的API接口配置

安装flask-cors

pip install flask-cors

第一种:使用@cross_origin装饰器

@app.route("/")
@cross_origin()
def helloWorld():return "Hello, cross-origin-world!"

CORS参数说明 

装饰器参数

类型

Head字段

说明

origins

列表、字符串或正则表达式

Access-Control-Allow-Origin

配置允许跨域访问的源,*表示全部允许

methods

列表、字符串

Access-Control-Allow-Methods

配置跨域支持的请求方式,如:GET、POST

expose_headers

列表、字符串

Access-Control-Expose-Headers

自定义请求响应的Head信息

allow_headers

列表、字符串或正则表达式

Access-Control-Request-Headers

配置允许跨域的请求头

supports_credentials

布尔值

Access-Control-Allow-Credentials

是否允许请求发送cookie,false是不允许

max_age

整数、字符串

Access-Control-Max-Age

预检请求的有效时长

第二种:使用CORS函数

#################### 应用全局配置 ####################
from flask_cors import *app = Flask(__name__)
CORS(app, supports_credentials=True, resources=r"/*")@app.route("/api/v1/users")
def list_users():return "user example"#################### 单独Blueprints配置 ####################
api_v1 = Blueprint('API_v1', __name__)
CORS(api_v1) @api_v1.route("/api/v1/users/")
def list_users():return "user example"

CORS参数说明

参数

类型

Head字段

说明

resources

字典、迭代器或字符串

全局配置允许跨域的API接口

origins

列表、字符串或正则表达式

Access-Control-Allow-Origin

配置允许跨域访问的源,*表示全部允许

methods

列表、字符串

Access-Control-Allow-Methods

配置跨域支持的请求方式,如:GET、POST

expose_headers

列表、字符串

Access-Control-Expose-Headers

自定义请求响应的Head信息

allow_headers

列表、字符串或正则表达式

Access-Control-Request-Headers

配置允许跨域的请求头

supports_credentials

布尔值

Access-Control-Allow-Credentials

是否允许请求发送cookie,false是不允许

max_age

整数、字符串

Access-Control-Max-Age

预检请求的有效时长

注意:继承Resource类来写的RESTful-API接口

继承Resource类来写的RESTful-API接口不能使用上述办法。解决办法是在需要支持跨域请求的API类下,添加一个类方法options,就可以解决跨域问题

原因是跨域问题请求的时候,无论是POST请求还是PUT请求,前端都会优先发起一个OPTIONS请求确认请求允许范围.那么在解决跨域请求时,只需要在每个资源url中加入options请求方式,并返回适当的响应头信息就能解决跨域问题.

class YourAPI(Resource):def options(self):return {'Allow': '*'}, 200, {'Access-Control-Allow-Origin': '*','Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, POST, DELETE, PUT','Access-Control-Allow-Headers': 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild',}

具体可配置参数解释:

  • Access-Control-Allow-Origin
    这个头部信息由服务器返回,用来明确指定那些客户端的域名允许访问这个资源。它的值可以是:

    -使用" * " —— 允许任意域名

    • 一个完整的域名名字(比如:https://example.com)

    如果你需要客户端传递验证信息到头部(比如:cookies)。这个值不能为 * —— 必须为完整的域名(这点很重要)。

  • Access-Control-Allow-Credentials
    这个头部信息只会在服务器支持通过cookies传递验证信息的返回数据里。它的值只有一个就是 true。跨站点带验证信息时,服务器必须要争取设置这个值,服务器才能获取到用户的cookie。

  • Access-Control-Allow-Headers
    提供一个逗号分隔的列表表示服务器支持的请求数据类型。假如你使用自定义头部(比如:x-authentication-token 服务器需要在返回OPTIONS请求时,要把这个值放到这个头部里,否则请求会被阻止)。

  • Access-Control-Expose-Headers
    相似的,这个返回信息里包含了一组头部信息,这些信息表示那些客户端可以使用。其他没有在里面的头部信息将会被限制(译者注:这个头信息实战中使用较少)。

  • Access-Control-Allow-Methods
    一个逗号分隔的列表,表明服务器支持的请求类型(比如:GET, POST)

  • Origin
    这个头部信息,属于请求数据的一部分。这个值表明这个请求是从浏览器打开的哪个域名下发出的。出于安全原因,浏览器不允许你修改这个值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/454026.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Hibernate 中配置属性详解(hibernate.properties)

转自:https://blog.csdn.net/shudaqi2010/article/details/70324843 Hibernate能在各种不同环境下工作而设计的, 因此存在着大量的配置参数。多数配置参数都 有比较直观的默认值, 并有随 Hibernate一同分发的配置样例hibernate.properties 来展示各种配置选项。 所需…

1.3 使用电脑测试MC20的电话语音功能

需要准备的硬件 MC20开发板 1个https://item.taobao.com/item.htm?id562661881042GSM/GPRS天线 1根https://item.taobao.com/item.htm?id531979567261IPEX接口转SMA接口转接线 1根https://item.taobao.com/item.htm?id531979903836GPS有源天线 1根https://item.taobao.com/i…

前端之 AJAX

AJAX参数详细列表 参数名类型描述urlString(默认: 当前页地址) 发送请求的地址。typeString(默认: "GET") 请求方式 ("POST" 、 "GET")。注意:其它 HTTP 请求方法,如 PUT 和 DELETE ,但仅部分浏览器支持。tim…

buffer 和cache的区别

Cache:高速缓存,是位于CPU与主内存间的一种容量较小但速度很高的存储器。 由于CPU的速度远高于主内存,CPU直接从内存中存取数据要等待一定时间周期,Cache中保存着CPU刚用过或循环使用的一部分数据,当CPU再次使用该部分…

html5--1.18 div元素与布局

1.18 div元素与布局 1.元素的分类2.div元素与布局 1、元素的分类 块元素:主要特征是会产生换行效果,自动与其他元素分离成两行;通常可以作为容器在内部添加其他元素。已经学过的块元素有: h1~h6;hr;ul;ol;p;table......... 内联元素:不会产生…

python读取excel表格太大怎么办_Python:使用Openpyxl读取大型Excel工作表

尝试对load_workbook()类使用read_only True属性,这会导致您获得的工作表为IterableWroksheet,这意味着您只能迭代它们,您不能直接使用列/行号来访问其中的单元格值.根据documentation,这将提供接近恒定的存储器消耗.此外,您不需要关闭文件,语句将为您处理.示例 –import open…

五个优秀的视频格式转换工具

电脑、手机、DVD播放机、PSP……这么多的东西都可以播放视频,但是视频格式又千差万别的,我们该怎么办?这里,我们介绍五个功能强大且易于使用的媒体转换器,用于转换不同类型的视频文件。 一、Super (Windows) Super是一…

前端之 HTML

HTML Web服务本质 import socketsk socket.socket() sk.bind(("127.0.0.1", 8080)) sk.listen(5)while True:conn, addr sk.accept()data conn.recv(8096)conn.send(b"HTTP/1.1 200 OK\r\n\r\n")conn.send(b"<h1>Hello world!</h1>&…

接入指南

接入概述 接入微信公众平台开发&#xff0c;开发者需要按照如下步骤完成&#xff1a; 1、填写服务器配置 2、验证服务器地址的有效性 3、依据接口文档实现业务逻辑 下面详细介绍这3个步骤。 第一步&#xff1a;填写服务器配置 登录微信公众平台官网后&#xff0c;在公众平台官网…

艾宾浩斯记忆表格excel_Excel全年学习复习计划表(艾宾浩斯遗忘曲线)

最近准备考在职博士&#xff0c;刷刷学历&#xff0c;不得不又拿起必考的英语来&#xff0c;发现由于这几年敲代码&#xff0c;日常生活词汇忘了很多&#xff0c;只好买本考博词汇背诵&#xff0c;不过三十而立的人背起来确实费劲了&#xff0c;所以开始寻找好的背诵方法。又想…

七个帮助你处理Web页面层布局的jQuery插件

1.UI.Layout jQuery UI布局插件官方网站&#xff1a;http://layout.jquery-dev.com/index.cfm使用大小可折叠的嵌套面板和大量选项创建高级UI布局。布局可以创建任何你想要的UI外观; 从简单的标题或侧边栏到具有工具栏&#xff0c;菜单&#xff0c;帮助面板&#xff0c;状态栏…

前端之 CSS

CSS介绍 CSS&#xff08;Cascading Style Sheet&#xff0c;层叠样式表)定义如何显示HTML元素。 当浏览器读到一个样式表&#xff0c;它就会按照这个样式表来对文档进行格式化&#xff08;渲染&#xff09;。 CSS语法 CSS实例 每个CSS样式由两个组成部分&#xff1a;选择器…

在Window下编译OpenH323

前言&#xff1a; 本文只提供VC6.0的编译说明&#xff0c;如果想知道VC.Net下的编译过程请参看原文。 原文 &#xff1a; http://www.voxgratia.org/docs/pwlib_windows.html#msvc_headers 作者 &#xff1a;Craig Southeren 翻译 &#xff1a; Richard 原文…

shell中的条件判断和比较

1 shell 的$! ,$?, $$,$ $n $1 the first parameter,$2 the second... $# The number of command-line parameters. $0 The name of current program. $? Last command or functions return value. $$ The programs PID. $! …

matlab立体坐标定位_无惧密集建筑,小天才立体定位技术带来最强定位体验

如今&#xff0c;在可穿戴设备市场中&#xff0c;智能手表占据相当大一部分。而作为核心功能之一的定位&#xff0c;在智能手表中发挥着不可替代的作用&#xff0c;尤其是对于儿童电话手表而言。并且&#xff0c;在技术飞速进步&#xff0c;产品迭代加快的当前&#xff0c;儿童…

vue学习问题总结(一)

使用comopontent组件报错错误信息&#xff1a;vue.js:491 [Vue warn]: Unknown custom element: <todo-item> - did you register the component correctly? For recursive components, make sure to provide the "name" option.代码&#xff1a;<p>使用…

前端之 JavaScript 基础

JavaScript 概述 ECMAScript 和 JavaScript的关系 1996年11月&#xff0c;JavaScript 的创造者 Netscape(网景) 公司&#xff0c;决定将 JavaScript 提交给国际标准化组织 ECMA &#xff0c;希望这门语言能够成为国际标准。次年&#xff0c;ECMA发布262号标准文件&#xff08…

TCPMP0.72RC1的编译与移植以及自己另外做UI完整方法

我叫张挺&#xff0c;虽然开博&#xff0c;除了转了一篇黄色文章以外&#xff0c;技术文章从来没有写&#xff0c;所以呢&#xff0c;感到很不好意思&#xff01;于是决定还写一篇在网上也留点痕迹。我这里主要是介绍TCPMP的移植以及如何把这个鸟鸟整到自己的界面中来&#xff…

svga文件如何查看_电脑隐藏文件?如何查看隐藏文件 方法简单易学

大家好&#xff0c;我是小白一键重装软件的客服。如何查看隐藏文件呢&#xff1f;有时候不小心把文件夹勾选隐藏后文件就消失了&#xff0c;到底是怎么回事呢&#xff1f;其实这个是电脑上面一些设置开启了文件隐藏的功能哦&#xff0c;那么下面小白系统带你了解下如何查看隐藏…

jquery 的animate 的transform

$(function(){ var t 1000; $("#id").animate( {borderSpacing:180}, //180 指旋转度数 { step: function(now,fix){ $(this).css(-webkit-transform,rotate(nowdeg)); $(this).css(-ms-transform,rotate(nowdeg)); $(this).css(-moz-transform,rotate(nowdeg)); $(…