一、跨域问题详解

什么是跨域问题:

跨域问题只会出现在前后端分离项目中,在前后端分离项目中,前端发送ajax请求到后端会跨域问题拦截,导致这个问题的原因是“同源策略”

什么是同源策略:

前端请求的url地址必须与浏览器上的url地址处于相同上,也就是域名、端口、协议相同

-发送ajax请求的地址,必须跟浏览器上的url地址处于同域上 
	# 域 [域名,地址,端口,协议]
-请求成功,数据库返回,但是浏览器拦截

# 补充:浏览器中输入域名,没有加端口
    -www.baidu.com---->dns--->解析成地址  192.168.2.3----》没有加端口,默认是80
    -dns解析,先找本地的host文件
    -可以修改本地的host做映射

img

解决同源策略的方式:

  • 方式一:CORS 后端代码控制(本次所讲解)
  • 方式二:Nginx反向代理 (常用)
  • 方式三:搭建Node代理服务器
  • 方式四:JSONP 很老,不会用了,只能发get请求

1、CORS解决跨域问题

简介:

cors(跨域资源共享),第三方模块,后端技术,通过在响应头中加入固定的头,来解决跨域问题

cors基本流程:

浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。

  • 简单请求:
    • 浏览器发出CORS简单请求,只需要在头信息之中增加一个Origin字段。
  • 非简单请求:
    • 浏览器发出CORS非简单请求,会在正式通信之前,增加一次HTTP查询请求,称为”预检”请求(preflight)。浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错

什么是简单请求和非简单请求:

符合以下条件的请求就是简单请求,反之就是非简单请求

(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
    
    
 # 演示简单和非简单请求
    -如果是简单,直接发送真正的请求
    -如果是非简单,先发送options,如果允许,再发真正的请求

cors解决跨域问题:

# 第一步:安装
	pip install django-cors-headers
# 第二步:配置app
    INSTALLED_APPS = [
        'corsheaders'
    ]

# 第三步:配置中间件
    MIDDLEWARE = [
        'corsheaders.middleware.CorsMiddleware',
    ]
# 第四步:在配置文件配置
# 允许所有域
CORS_ORIGIN_ALLOW_ALL = True
# 允许的请求方式
CORS_ALLOW_METHODS = (
	'DELETE',
	'GET',
	'OPTIONS',
	'PATCH',
	'POST',
	'PUT',
	'VIEW',
)
# 允许请求头中加的东西
CORS_ALLOW_HEADERS = (
	'XMLHttpRequest',
	'X_FILENAME',
	'accept-encoding',
	'authorization',
	'content-type',
	'dnt',
	'origin',
	'user-agent',
	'x-csrftoken',
	'x-requested-with',
	'Pragma',
	'token',
)

2、自己编写代码解决跨域问题

思路:

  • 当请求进入django时,拦截请求进行判断
  • 如果是简单请求直接在响应头中加入"Access-Control-Allow-Origin"
    • 指是否允许该域名访问
  • 如果是非简请求,在响应头中加入"Access-Control-Allow-Headers"
    • 指是否允许在响应头中添加的字段
  • 将编写的代码注册成中间件,这样就不会出现跨域问题
from django.utils.deprecation import MiddlewareMixin
class CorsMiddleWare(MiddlewareMixin):
    def process_response(self,request,response):
        if request.method=="OPTIONS":  # 解决非简单请求的请求头
            #可以加*
            response["Access-Control-Allow-Headers"]="*"

        # 允许前端的地址,所有请求头允许
        response["Access-Control-Allow-Origin"] = "*"
        return response