跨域问题的CORS解决

跨域问题的CORS解决


1 为何会出现跨域问题:浏览器的同源策略

1.1 同源策略(Same-origin policy)

同源策略是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

同源策略的存在是为了防止恶意网站通过 JavaScript 等方式访问用户的敏感信息,或者以用户身份进行恶意操作。如果没有同源策略的限制,恶意网站可以在用户浏览器中执行任意脚本并访问其他站点的敏感数据。

1.2 同源策略的要求

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

同源指同协议、同域名、同端口,只有当这三者都相同时,才被认为是同一来源。

1.3 解决同源策略的方式

① 方式一:CORS

后端代码控制,咱们采用的方式

② 方式二:Nginx反向代理

反向代理(Reverse Proxy)方式是指以代理服务器来接受Internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给Internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器。

image-20230228192018670

③ 方式三:JSONP

只能发送get请求,较早之前的解决方式

④ 搭建Node代理服务器

2 CORS跨域资源共享(Cross-Origin Resource Sharing)

2.1 CORS解决跨域问题的原理

CORS需要【浏览器】和【服务器】同时支持

目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。

整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。

因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

2.2 CORS的基本流程

(1)CORS的两种请求

① 简单请求(simple request)

② 非简单请求(not-so-simple request)

如何分辨简单请求、非简单请求?

符合如下条件,就是简单请求

(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

(2)简单请求与非简单请求,如何解决跨域问题

① 简单请求(simple request)

浏览器发出CORS简单请求只需要在头信息之中增加一个Origin字段

response['Access-Control-Allow-Origin'] = '*'
② 非简单请求(not-so-simple request)

浏览器发出CORS非简单请求会在正式通信之前,增加一次HTTP查询请求,称为”预检”请求(preflight)

浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段

只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错

if request.method=="OPTIONS":  # 解决非简单请求的请求头
     # 可以加 *
     response["Access-Control-Allow-Headers"]="*"

(3)在中间件中添加新的中间件解决跨域问题

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

3 第三方模块django-cors-headers:解决跨域问题

在Django Rest Framework (DRF)中,处理跨域请求的一种常见方法是使用django-cors-headers包

django-cors-headers提供了一个中间件来允许跨域请求,以下是安装和配置django-cors-headers的步骤:

① 第一步:安装django-cors-headers

在终端使用以下命令安装django-cors-headers:

pip install django-cors-headers

② 第二步:在配置文件中配置app和配置中间件

在Django的设置文件中添加corsheaders应用程序和中间件:

INSTALLED_APPS = [
    # ...
    'corsheaders',
    # ...
]

MIDDLEWARE = [
    # ...
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    # ...
]

③ 第三步:添加以下配置项以允许跨域请求:

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',
)

⑤ 配置特定的源

这将允许来自所有源的跨域请求。如果你只想允许特定的源,可以将CORS_ORIGIN_ALLOW_ALL设置为False,然后将允许的源添加到CORS_ORIGIN_WHITELIST中。

CORS_ORIGIN_ALLOW_ALL = False

CORS_ORIGIN_WHITELIST = [
    'http://localhost:3000',
    'https://example.com'
]

以上步骤完成后,你的DRF应用程序就能够处理跨域请求了。

posted @ 2023-02-28 20:18  Duosg  阅读(167)  评论(0编辑  收藏  举报