共计 2479 个字符,预计需要花费 7 分钟才能阅读完成。
一. 浏览器的同源策略
1. 同源策略介绍
同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说 Web 是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现
2. 同源策略判断依据
-
请求的 url 地址, 必须与浏览器上的 url 地址处于同域上, 也就是域名, 端口, 协议相同
-
比如: 我在本地上的域名是 127.0.0.1:8000, 请求另外一个域名:127.0.0.1:8001 一段数据
-
浏览器上就会报错,个就是同源策略的保护, 如果浏览器对 javascript 没有同源策略的保护, 那么一些重要的机密网站将会很危险
二.CORS : 跨域资源共享简介(后端技术)
CORS 需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE 浏览器不能低于 IE10
整个 CORS 通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS 通信与同源的 AJAX 通信没有差别,代码完全一样。浏览器一旦发现 AJAX 请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉
因此,实现 CORS 通信的关键是服务器。只要服务器实现了 CORS 接口,就可以跨源通信
ps : 出现跨域问题 (前后端分离项目不可避免) 是因为浏览器拦截了, 解决方法:
CORS (跨域资源共享: 后端技术) # 主流采用的方案, 使用第三方插件
前端代理 # node 起了一个服务, 只在测试阶段使用(正向代理)
jsonp # 只能解决 get 请求跨域, 本质原理是使用了某些标签不限制跨域(img,script)
nginx 转发 # 后面详细讲
三.CORS 基本流程
1.CORS 请求分类
- 简单请求 (simple request)
- 非简单请求 (not-so-simple request)
2. 请求分类解释
- 简单请求:简单请求只发一次
- 非简单请求:发送两次,第一次是 options 请求,第二次是真正的请求
四. 两种请求详解
只要同时满足以下两大条件,就属于简单请求
凡是不同时满足下面两个条件,就属于非简单请求
1. 请求方法是以下三种方法之一
- HEAD
- GET
- POST
2.HTTP 的头信息不超出以下几种字段
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- Content-Type:只限于三个值 :
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain
五. 浏览器对于这两种请求的处理
1. 简单请求, 支持跨域
- 需服务器设置响应头:
Access-Control-Allow-Origin =‘域名’或‘*’
2. 复杂请求, 支持跨域
由于复杂请求时,首先会发送“预检”请求,如果“预检”成功,则发送真实数据, 所以:
- “预检”请求时,允许请求方式, 则需要服务器设置响应头:
Access-Control-Request-Method
- “预检”请求时,允许请求头, 则需要服务器设置响应头:
Access-Control-Request-Headers
六.Django 项目中支持 CORS
1. 在返回结果中添加允许信息 (简单请求)
def test(request):
import json
obj=HttpResponse(json.dumps({'name':'shawn'}))
# obj['Access-Control-Allow-Origin']='*' # 允许所有
obj['Access-Control-Allow-Origin']='http://127.0.0.1:8004' # 只允许该域
return obj
2. 在中间件中处理复杂请求和简单请求
from django.utils.deprecation import MiddlewareMixin
class CorsMiddleWare(MiddlewareMixin):
def process_response(self,request,response):
if request.method=="OPTIONS":
#可以加 '*'
response["Access-Control-Allow-Headers"]="Content-Type"
response["Access-Control-Allow-Origin"] = "http://localhost:8080"
return response
七. 使用第三方 django-cors-headers 解决跨域问题
1. 安装
pip install django-cors-headers
2. 在配置文件中进行应用注册
INSTALLED_APPS = [
....
'corsheaders',
]
3. 添加中间件
MIDDLEWARE = [ # Or MIDDLEWARE_CLASSES on Django < 1.10
...
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
]
4. 在配置文件中添加相关配置
CORS_ALLOW_CREDENTIALS = True
# 允许所有域(与下面的一个配置相同, 保留一个就行)
CORS_ORIGIN_ALLOW_ALL = True
# 允许的域, "*" : 所有, (如果是全部, 则与上面的相同, 保留一个就行)
CORS_ORIGIN_WHITELIST = ('*')
# 允许的请求方式
CORS_ALLOW_METHODS = (
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
'VIEW',
)
# 允许的 HTTP 头信息字段
CORS_ALLOW_HEADERS = (
'XMLHttpRequest',
'X_FILENAME',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
'Pragma',
)