同源:ip和端口,以及协议都相同

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

浏览器的安全策略:请求从一个域发到了另外一个域,另外一个域响应了,浏览器把数据拦截了

基于浏览器的前后端分离的项目存在跨域问题

pycharm监听了8000端口,它可以让其多个子线程也监听这个端口,正常情况是:不能多个程序监听同一个端口

CORS:跨域资源共享,一个域允许其他的域来自己这里拿数据,本质就是在响应头部加入允许,允许某些域和某些头

浏览器将CORS请求分为两类:简单请求和非简单请求

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

如何“预检”
     => 如果复杂请求是PUT等请求,则服务端需要设置允许某请求,否则“预检”不通过
        Access-Control-Request-Method
     => 如果复杂请求设置了请求头,则服务端需要设置允许某请求头,否则“预检”不通过
        Access-Control-Request-Headers
        

支持跨域,简单请求

服务器设置响应头:Access-Control-Allow-Origin = ‘域名’ 或 ‘*’

支持跨域,复杂请求

由于复杂请求时,首先会发送“预检”请求,如果“预检”成功,则发送真实数据。

  • “预检”请求时,允许请求方式则需服务器设置响应头:Access-Control-Request-Method
  • “预检”请求时,允许请求头则需服务器设置响应头:Access-Control-Request-Headers

简单请求只发一次请求,同时满足以下条件

(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中间件
class MyMiddle(MiddlewareMixin):
    def process_response(self, request, response):
        # 允许所有的域
        response['Access-Control-Allow-Origin'] = '*'
        # 如果是非简单请求,浏览器会先发送一次OPTIONS请求
        if request.method == 'OPTIONS':
            # 只写了一个头Content-Type',还有其他头
            response['Access-Control-Allow-Headers'] = 'Content-Type'
            # response['Access-Control-Allow-Headers'] = 'authorization'
        return response

配置第三方的CORS处理模块django-cors-headers
  1. 先安装:pip install django-cors-headers

  2. 在配置文件的app里面注册:'corsheaders',

  3. 添加到中间件里面:'corsheaders.middleware.CorsMiddleware',

  4. 在配置文件里面添加:

    CORS_ORIGIN_ALLOW_ALL = True
    
    CORS_ALLOW_METHODS = (
    	'DELETE',
    	'GET',
    	'OPTIONS',
    	'PATCH',
    	'POST',
    	'PUT',
    	'VIEW',
    )
    
    CORS_ALLOW_HEADERS = (	
        # jwt 认证的头
    	'authorization',
        # 格式的头
    	'content-type',	
    )