09 跨域请求详解

512次阅读
没有评论

共计 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',
)
正文完
 
shawn
版权声明:本站原创文章,由 shawn 2023-06-16发表,共计2479字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)