CORB(Cross-Origin Read Blocking)
浏览器在加载可以跨域资源时,在将资源载入页面时对其进行识别与拦截等一系列处理。
同源策略(Same-Origin Policy)
指域名,协议,端口相同。不同源的客户端脚本(javascript、ActionScript)在没明确授权的情况下,不能读写对方的资源。浏览器允许包含在页面A的脚本访问第二个页面B的数据资源,这一切是建立在A和B页面是同源的基础上。
跨域访问的处理方法:
一、通过后台服务端进行对其他域的请求
二、通过flask的flask-cors第三方扩展
三、jsonp: json with padding 创建一个回调函数,然后在远程服务上调用这个函数并且将JSON数据形式作为参数传递,完成回调。将JSON数据填充进回调函数,这就是JSONP的JSON+Padding的含义。
四、设置响应头
五、django的第三方扩展django-cors-headers
一、通过后台服务端进行对其他域的请求
def req(request):
response = requests.get("http://127.0.0.1:5000/newsdetail/1")
# 设置字节类型
response.encoding = 'utf-8'
return render(request,'req.html',{"result":response.text})
二、通过flask的flask-cors第三方扩展
pip install flask-cors
# 使用第三方扩展 exts中创建
from flask_cors import CORS
cors= CORS()
# 与app进行绑定即可
cors.init_app(app=app,supports_credentials=True)
三、jsonp: json with padding
jsonp类型:String
在一个 jsonp 请求中重写回调函数的名字。这个值用来替代在 “callback=?” 这种 GET 或 POST 请求中 URL参数里的 “callback” 部分,比如 {jsonp:'onJsonPLoad'}
会导致将 "onJsonPLoad=?"
传给服务器。
jsonpCallback 类型:String
为 jsonp 请求指定一个回调函数名。这个值将用来取代 jQuery 自动生成的随机函数名。这主要用来让 jQuery 生成独特的函数名,这样管理请求更容易,也能方便地提供回调函数和错误处理。
def jsonp1(request):
return render(request,'jsonp1.html')
def jsonp2(request):
ret = {"status": 200, "msg": "jsonp2"}
func_name = request.GET.get("callback")
# print("{}({})".format(func_name, json.dumps(ret))) # callback({"status": 200, "msg": "jsonp2"})
return HttpResponse(str("{}({})").format(func_name, json.dumps(ret)), content_type='text/javascript')
jsonp方法的常见错误:
Cross-Origin Read Blocking (CORB) blocked cross-origin response http://127.0.0.1:8002/jsonp2?&callback=callback&_=1618987609564 with MIME type text/html.
原理:
X-Content-Type-Options(:nosniff) 相当于一个提示标志,被服务器用来提示客户端须遵循在Content-Type首部中对MIME类型的设定,不能对其进行修改。从而禁用了客户端(浏览器)的MIME类型嗅探行为(即把不可执行的MIME类型转变为可执行的MIME类型)。
指定值为nosniff时,会拒绝以下两种请求: 请求类型:style,MIME类型不是“text/css”
请求类型:script,MIME类型不是“Javascript类型”
Javascript类型有text/javascript、application/javascript、application/x-javascript等
所以当服务端出现response.addHeader("X-Content-Type-Options", "nosniff")
安全响应头,且未指定Content-Type为Javascript类型类型时,jsonp请求跨域资源时会出现如上CORB或拒绝解析的问题。
修改方法如下:
1.去除服务端response.addHeader(“X-Content-Type-Options”, “nosniff”)的配置,但可能造成一些安全上的问题
2.服务指定Content-Type为Javascript类型的一种 content_type=‘text/javascript’
3.启用jsonp,将跨域的数据请求转到本站服务器,由本站服务器去做跨域请求,即跳过浏览器同源策略的限制
四、设置响应头
# 设置响应头
def jsonp3(request):
return render(request,'jsonp3.html')
def jsonp4(request):
obj = JsonResponse([ '西游记2', '三国演义2', '水浒传2' ], safe=False)
obj[ "Access-Control-Allow-Origin" ] = "http://127.0.0.1:8000"
# 只有这个ip和端口来的请求,我才给他数据,其他的请求浏览器帮我拦着
return obj
五、django的第三方扩展django-cors-headers
def cors1(request):
return render(request,'cors1.html')
def cors2(request):
obj = JsonResponse([ '西游记2', '三国演义2', '水浒传2' ], safe=False)
return obj
配置方法
pip install django-cors-headers
# 添加app setting:放到最后
INSTALLED_APPS = (
'corsheaders',
)
# 添加中间件 注意添加的顺序
MIDDLEWARE = [
...
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',]
# 配置允许跨站访问本站的地址
CORS_ORIGIN_ALLOW_ALL = False
CORS_ORIGIN_WHITELIST = (
'http://127.0.0.1:8000',
)
CORS_ORIGIN_WHITELIST = () # 默认值是全部
CORS_ORIGIN_REGEX_WHITELIST = ('^(https?://)?(\w+.)?>google.com$', )# 或者定义允许的匹配路径正则表达式.
# 设置允许访问的方法
CORS_ALLOW_METHODS = (
'GET',
'POST',
'PUT',
'PATCH',
'DELETE',
'OPTIONS'
)
# 设置允许的header:
CORS_ALLOW_HEADERS = (
'x-requested-with',
'content-type',
'accept',
'origin',
'authorization',
'x-csrftoken'
)
项目总体:https://github.com/zxy1013/Cross-Origin