阿里巴巴怎么做企业网站,桂林漓江图片高清,html网站建设代码,911制作网站一、什么是跨域 跨域是指#xff1a;浏览器A从服务器B获取的静态资源#xff0c;包括Html、Css、Js#xff0c;然后在Js中通过Ajax访问C服务器的静态资源或请求。即#xff1a;浏览器A从B服务器拿的资源#xff0c;资源中想访问服务器C的资源。
同源策略是指#xff1a;…一、什么是跨域 跨域是指浏览器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-urlencodedmultipart/form-data或text/plain之一复杂请求Preflighted Request发起的Http请求符合其中之一 1.包含了自定义请求头 2.请求动词不是GET、HEAD或POST 3.动词是POST时 Content-Type不是application/x-www-form-urlencodedmultipart/form-data或text/plain。 即简单请求的相反凭证请求Requests with Credential发起的Http请求中带有凭证
简单请求
简单请求的发送从代码上来看和普通的XHR没太大区别但是HTTP头当中要求总是包含一个域Origin的信息。该域包含协议名、地址以及一个可选的端口。不过这一项实际上由浏览器代为发送并不是开发者代码可以触及到的。
简单请求的部分响应头如下
Access-Control-Allow-Origin必含。不填请求按失败处理。该项控制数据的可见范围如果希望数据对任何人都可见可以填写*。Access-Control-Allow-Credentials可选。该项标志着请求当中是否包含cookies信息只有一个可选值true必为小写。如果不包含cookies请略去该项而不是填写false。这一项与XmlHttpRequest2对象当中的withCredentials属性应保持一致即withCredentials为true时该项也为truewithCredentials为false时省略该项不写。反之则导致请求失败。Access-Control-Expose-Headers可选 – 该项确定XmlHttpRequest2对象当中getResponseHeader()方法所能获得的额外信息。通常情况下getResponseHeader()方法只能获得如下的信息当你需要访问额外的信息时就需要在这一项当中填写并以逗号进行分隔 Cache-ControlContent-LanguageContent-TypeExpiresLast-ModifiedPragma
如果仅仅是简单请求那么即便不用CORS也没有什么大不了但CORS的复杂请求就令CORS显得更加有用了。简单来说任何不满足上述简单请求要求的请求都属于复杂请求。比如说你需要发送PUT、DELETE等HTTP动作或者发送Content-Type: application/json的内容。
复杂请求
复杂请求先发送一种预请求此时作为服务端也需要返回预回应作为响应。预请求实际上是对服务端的一种权限请求只有当预请求成功返回实际请求才开始执行。预请求以OPTIONS形式发送当中同样包含域并且还包含了两项CORS特有的内容
Access-Control-Request-Method – 该项内容是实际请求的种类可以是GET、POST之类的简单请求也可以是PUT、DELETE等等。Access-Control-Request-Headers – 该项是一个以逗号分隔的列表当中是复杂请求所使用的头部。
显而易见这个预请求实际上就是在为之后的实际请求发送一个权限请求在预回应返回的内容当中服务端应当对这两项进行回复以让浏览器确定请求是否能够成功完成。复杂请求的部分响应头及解释如下
Access-Control-Allow-Origin必含 – 和简单请求一样的必须包含一个域。Access-Control-Allow-Methods必含 – 这是对预请求当中Access-Control-Request-Method的回复这一回复将是一个以逗号分隔的列表。尽管客户端或许只请求某一方法但服务端仍然可以返回所有允许的方法以便客户端将其缓存。Access-Control-Allow-Headers当预请求中包含Access-Control-Request-Headers时必须包含 – 这是对预请求当中Access-Control-Request-Headers的回复和上面一样是以逗号分隔的列表可以返回所有支持的头部。这里在实际使用中有遇到所有支持的头部一时可能不能完全写出来而又不想在这一层做过多的判断没关系事实上通过request的header可以直接取到Access-Control-Request-Headers直接把对应的value设置到Access-Control-Allow-Headers即可。Access-Control-Allow-Credentials可选 – 和简单请求当中作用相同。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,POSTresp.headers[Access-Control-Allow-Headers] x-requested-with,content-typereturn 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 是否允许请求发送cookiefalse是不允许 max_age 整数、字符串 Access-Control-Max-Age 预检请求的有效时长
第二种使用CORS函数
#################### 应用全局配置 ####################
from flask_cors import *app Flask(__name__)
CORS(app, supports_credentialsTrue, resourcesr/*)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 exampleCORS参数说明 参数 类型 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 是否允许请求发送cookiefalse是不允许 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 这个头部信息属于请求数据的一部分。这个值表明这个请求是从浏览器打开的哪个域名下发出的。出于安全原因浏览器不允许你修改这个值。