如何使用CORS解决跨域问题

一,为什么会有跨域问题

  跨域问题的出现,是因为浏览器的同源策略对ajax请求进行阻拦了,但是并不是所有的请求都给做当做跨域,;像是一般的href属性,a标签什么的都不进行拦截

二,什么是同源策略

  同源策略是一种约定,它是浏览器最核心也会是最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。

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

  如果不同,就会报错:

已拦截跨源请求:同源策略禁止读取位于 http://127.0.0.1:8001/SendAjax/ 的远程资源。(原因:CORS 头缺少 ‘Access-Control-Allow-Origin‘)。

  实际上的结果是,请求以及被发送过去了,目标服务器也对做出了响应,只是浏览器对非同源请求的放回结果做了拦截。

三,CORS简介

  CORS,跨域资源共享,它需要浏览器和服务器同事支持,目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。

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

  要实现cors通信,主要是在服务器,也就是获得数据的一方做处理。

四,cors基本的流程

  1,浏览器将请求分为两类,一类是简单请求,一类是非简单请求,满足下列条件的就是简单请求,否则即使非简单请求:

条件:
    1、请求方式:HEAD、GET、POST
    2、请求头信息:
        Accept
        Accept-Language
        Content-Language
        Last-Event-ID
        Content-Type 对应的值是以下三个中的任意一个
                                application/x-www-form-urlencoded
                                multipart/form-data
                                text/plain

注意:同时满足以上两个条件时,则是简单请求,否则为复杂请求

  2,简单请求和复杂请求的区别:

    简单请求:一次请求

    非简单请求:两次请求,在发送数据之前会先发第一次请求做预检,只有预检通过后在发一次请求作为数据传输。

  3,关于预检:

- 请求方式:OPTIONS
- “预检”其实做检查,检查如果通过则允许传输数据,检查不通过则不再发送真正想要发送的消息
- 如何“预检”
     => 如果复杂请求是PUT等请求,则服务端需要设置允许某请求,否则“预检”不通过
        Access-Control-Request-Method
     => 如果复杂请求设置了请求头,则服务端需要设置允许某请求头,否则“预检”不通过
        Access-Control-Request-Headers

  4,CORS优缺点

    CORS的优点:可以发任意请求

    CORS的缺点:上是复杂请求的时候得先做一个预检,再发真实的请求,发了两次请求会有性能上的损耗。

五,实现CORS请求

  局部使用:

    简单请求(get)客户端:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<button id="a" class="btn btn-success">go</button>
<script>
    $("#a").click(function () {
        $.ajax({
            url:‘http://127.0.0.1:8000/time/‘,
            type:‘get‘,
            success:function (data) {
                alert(data)
            }
            }
        )
    })
</script>
</body>
</html>

    简单请求服务端:

def get_time(request):
    if request.method == ‘GET‘:
        ntime = time.strftime(‘%Y-%m-%d %X‘)
        obj = HttpResponse(ntime)
        obj[‘Access-Control-Allow-Origin‘] = ‘http://127.0.0.1:8001‘
        return obj

    复杂请求(post+contentType)客户端:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<button id="a" class="btn btn-success">go</button>
<script>
    $("#a").click(function () {
        $.ajax({
            url:‘http://127.0.0.1:8000/money/‘,
            type:‘post‘,
            contentType:‘application/json‘,
            data:{"name":"yjh"},
            success:function (data) {
                alert(data)
            }
            }
        )
    })
</script>
</body>
</html>

    复杂请求服务端:

from django.http import QueryDict
def get_money(request):
    # print(request.body)
    if not request.body:
        obj = HttpResponse(‘1000000000000‘)
    else:
        data = request.body # post请求传过来的数据以二进制的形式存放于request.body
        # 将request.body的二进制数据转化为字典形式
        dic = QueryDict(data.decode(‘utf-8‘),encoding=‘utf-8‘)
        name = dic.get(‘name‘)
        obj = HttpResponse(name)
    if request.method == ‘OPTIONS‘:
        obj[‘Access-Control-Allow-Headers‘] = ‘Content-Type‘
    obj[‘Access-Control-Allow-Origin‘] = ‘http://127.0.0.1:8001‘
    return obj

六:全局配置

  由于是全局配置,所以应该写在中间件中。然而,我们知道浏览器是在返回的时候出现的禁用,因此我们我们需要重写process_response方法。

  第一步:在应用文件夹根目录中,新建一个my_middleware.py文件

  第二步:在该py文件夹中写上:

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

  第三步:在settings.py中配置:

MIDDLEWARE = [
    ‘app01.my_middleware.CorsMiddleware‘,
    ‘django.middleware.security.SecurityMiddleware‘,
    ‘django.contrib.sessions.middleware.SessionMiddleware‘,
    ‘django.middleware.common.CommonMiddleware‘,
    # ‘django.middleware.csrf.CsrfViewMiddleware‘,
    ‘django.contrib.auth.middleware.AuthenticationMiddleware‘,
    ‘django.contrib.messages.middleware.MessageMiddleware‘,
    ‘django.middleware.clickjacking.XFrameOptionsMiddleware‘,
]

原文地址:https://www.cnblogs.com/zy740/p/11771665.html

时间: 2024-10-25 23:00:32

如何使用CORS解决跨域问题的相关文章

一步一步学习SignalR进行实时通信_3_通过CORS解决跨域

原文:一步一步学习SignalR进行实时通信_3_通过CORS解决跨域 一步一步学习SignalR进行实时通信\_3_通过CORS解决跨域 SignalR 一步一步学习SignalR进行实时通信_3_通过CORS解决跨域 前言 关于start()的补充 跨域解决方案 JSONP CORS CORS跨域演示 结束语 参考文献 前言 这周工作比较忙,一直没有时间学习SignalR,大致希望一周能写一篇关于SignalR的文章.上一篇用Persistent Connections方式实现了个简单的在线

Spring Boot中通过CORS解决跨域问题

今天和小伙伴们来聊一聊通过CORS解决跨域问题. 同源策略 很多人对跨域有一种误解,以为这是前端的事,和后端没关系,其实不是这样的,说到跨域,就不得不说说浏览器的同源策略. 同源策略是由Netscape提出的一个著名的安全策略,它是浏览器最核心也最基本的安全功能,现在所有支持JavaScript的浏览器都会使用这个策略.所谓同源是指协议.域名以及端口要相同.同源策略是基于安全方面的考虑提出来的,这个策略本身没问题,但是我们在实际开发中,由于各种原因又经常有跨域的需求,传统的跨域方案是JSONP,

使用CORS解决跨域问题

1.什么是动静分离 "动"与"静" 在弄清动静分离之前,我们要先明白什么是动,什么是静. 在Web开发中,通常来说,动态资源其实就是指那些后台资源,而静态资源就是指Html.img.js.css等文件. 动静分离就是将动态资源和静态资源分开,将静态资源部署在Nginx上,当一个请求来的时候,如果是静态资源的请求,就直接到nginx配置的静态资源目录下面获取资源,如果是动态资源的请求,nginx利用反向代理的原理,把请求转发给后台应用去处理,从而实现动静分离. 好处

Django 【第二十篇】后端CORS解决跨域问题

一.为什么会有跨域问题? 是因为浏览器的同源策略是对ajax请求进行阻拦了,但是不是所有的请求都给做跨域,像是一般的href属性,a标签什么的都不拦截. 二.解决跨域问题的两种方式 JSONP CORS 三.JSONP 先简单来说一下JSONP,具体详细详见上面JSONP JSONP是json用来跨域的一个东西.原理是通过script标签的跨域特性来绕过同源策略.(创建一个回调函数,然后在远程服务上调用这个函数并且将json数据形式作为参数传递,完成回调). 四.CORS跨域 随着技术的发展,现

Web API中使用CORS解决跨域(暂存)

Web API中使用Cros解决跨域 如果两个页面的协议,端口和域名都相同,则两个页面具有相同的源,注:IE不考虑端口,同源策略不会阻止浏览器发送请求,但是它会阻止应用程序看到响应.如下图所示 CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)它允许浏览器向跨源服务器,发出请求.CORS需要浏览器和服务器同时支持,目前,主流的浏览器都支持CORS,因此实现CORS通信的关键是服务器.CORS是通过目标服务器返回的Header设

后端CORS解决跨域问题

一 . 为什么会有跨域问题 是因为浏览器的同源策略是对ajax请求进行阻拦了,但是不是所有的请求都给做跨域,像是一般的href 属性,a标签什么的都不拦截. 二 . 解决跨域的方法 解决跨域有两种方法 : JSONP CORS 三 . JSONP 简单说下JSONP,详细的在上一篇 JSONP时json用来跨域的一个东西,原理是通过script标签的跨域特性来绕过同源策略,(创建一个回调函数,然后在远程服务商调用这个函数并且将json数据形式作为参数传递,完成回调). 原文地址:https://

cors解决跨域

什么是cors CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing). 它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制. CORS需要浏览器和服务器同时支持.目前,所有浏览器都支持该功能,IE浏览器不能低于IE10. 浏览器端: 目前,所有浏览器都支持该功能(IE10以下不行).整个CORS通信过程,都是浏览器自动完成,不需要用户参与. 服务端: CORS通信与AJAX没有任

SpringBoot 中通过 CORS 解决跨域问题

同源策略 源(origin)就是协议(http).域名(localhost)和端口号(8080),同源是指协议.域名以及端口要相同. No 'Access-Control-Allow-Origin' header is present on the requested resource. 后端使用CORS(跨域源资源共享)(CORS,Cross-origin resource sharing)实现跨域 全局配置 @Configuration public class WebMvcConfig i

SpringBoot使用CORS解决跨域请求问题

什么是跨域? 同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源. 同源策略是浏览器安全的基石. 如果一个请求地址里面的协议.域名和端口号都相同,就属于同源. 举个栗子 判断下面URL是否和 http://www.a.com/a/a.html 同源 http://www.a.com/b/b.html 同源 http://www.b.com/a/a.html 不同源,域名不相同 https://www.a.com/b/b.html 不同源,协议不相同 htt