Django 多方式实现跨域访问

一、什么是跨域

1.1 跨越介绍

跨域,是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript实施的安全限制。 这里说明一下,无法跨域是浏览器对于用户安全的考虑,如果自己写个没有同源策略的浏览器,完全不用考虑跨域问题了。
域可以理解为: 协议 + 域名 + 端口号

  • 在前后端不分离的项目中,前端使用ajax发起请求时,前端发起请求的域与后端定义API的域一致,故不会存在跨域问题
  • 在前后端分离的项目中,前端使用ajax或者axios发起请求,前后端各自运行在自己的域下,所以在发起请求的时候就会造成跨域,比如前端使用脚手架创建,运行在 http://127.0.0.1:8080 后端运行在 http://127.0.0.1:8000 端口,当前端发起请求时,因为域(端口不一致)不同,就会造成跨域,浏览器便会阻止该请求。

1.2 跨域分类

跨域请求分为2种,一种是简单请求,一种是复杂请求。

  • *简单请求
只要同时满足以下两大条件,就属于简单请求
HTTP 方法是下列之一
    - HEAD
    - GET
    - POST

HTTP 头信息不超出以下几种字段
    - Accept
    - Accept-Language
    - Content-Language
    - Last-Event-ID
    - Content-Type 只能是下列中的一个类型
            application/x-www-from-urlencoded
            multipart/form-data
            text/plain

任何一个不满足上述要求的请求,即会被认为是复杂请求
复杂请求会先发出一个预请求,我们也叫预检, OPTIONS请求

二、同源策略

浏览器只阻止表单以及ajax请求,并不会阻止src请求,所以我们的cdn,图片等src请求都可以发~~

2.1 Ajax测试

当我们向后端发起GET请求时,后端没有做跨域访问。

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://unpkg.com/axios/dist/axios.min.js">script>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js">script>
    <title>跨域请求测试title>
head>

<body>
    <div id="app">
        <button  @click="Send">发送请求button>
    div>
body>
<script>
    new Vue({
        el:"#app",
        methods:{
            Send(){
                axios.get('http://127.0.0.1:8000/api/test/')
                  .then(function (response) {

                    console.log(response);
                  })
                  .catch(function (error) {

                    console.log(error);
                  })
            }
        }
    })
script>
html>

浏览器给出提示。从origin ‘null’访问’http://127.0.0.1:8000/api/test/’的XMLHttpRequest已经被CORS[跨域资源共享]策略阻止:没有’Access- control – allow – origin ‘头在请求的资源上存在。

Django 多方式实现跨域访问
我们在后端也发现,请求已经进来了,并成功返回了。所以数据被浏览器给劫持了
Django 多方式实现跨域访问

2.2 src 测试

当我们使用 img script 标签的src来发起一个GET请求,会触发CORB(Cross-Origin Read Blocking )跨域读取阻塞。
当跨域请求回来的数据 MIME type 同跨域标签应有的 MIME 类型不匹配时,浏览器会启动 CORB 保护数据不被泄漏,被保护的数据类型只有 html xmljson。很明显 <script> </code>和 <code><img> </code>等跨域标签应有的<code> MIME type</code> 和<code> html</code> 、<code>xml</code>、<code>json</code> 不一样。<br><img src="https://img-blog.csdnimg.cn/e4a6f695c2a14a5b91081bab4f700729.png"></p><blockquote><p>详情可以看这篇文章 https://juejin.cn/post/6844903831373889550</p></blockquote><h1><a id="_83">;</a>三,解决跨域访问</h1><h2>3.1 请求方式添加Headers来解决跨域问题</h2><h3><a id="311_GET_85"></a>3.1.1 简单请求处理----以GET请求为例</h3><p>在前面的测试时,我们发现请求已经到达,响应后被浏览器拦截了,所以需要我们告诉浏览器不要拦截<br>我这里使用的是django作为Web后端开发框架,当我们发起GET请求时,我们在后端添加浏览器所需要对应的请求体参数<code>Access-Control-Allow-Origin</code></p><p>1.<strong>在TestView视图函数添加请求参数</strong></p><pre><code class="prism language-python"><span class="token keyword">def</span> <span class="token function">TestView</span><span class="token punctuation">(</span>request<span class="token punctuation">)</span><span class="token punctuation">:</span> data <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token string">"user"</span><span class="token punctuation">:</span> <span class="token string">"jack"</span><span class="token punctuation">,</span> <span class="token string">"pwd"</span><span class="token punctuation">:</span> <span class="token string">"123"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> request<span class="token punctuation">.</span>method <span class="token operator">==</span> <span class="token string">'GET'</span><span class="token punctuation">:</span> <span class="token keyword">return</span> HttpResponse<span class="token punctuation">(</span>json<span class="token punctuation">.</span>dumps<span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">,</span>content_type<span class="token operator">=</span><span class="token string">'application/json'</span><span class="token punctuation">)</span> </code></pre><p>4.<strong>重新启动,在此进行测试</strong><br>前端代码如上,测试成功<br><img src="https://img-blog.csdnimg.cn/d40d15e855a04824943b7214cef6444c.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAUmkwbg==,size_20,color_FFFFFF,t_70,g_se,x_16"><br><strong>注意</strong>:在进行post测试时,为了方便,我们需要注释掉django的csrf中间件,这是django自带的防止跨域请求伪造。<br>增加一个post方法判断</p><pre><code class="prism language-python"><span class="token keyword">def</span> <span class="token function">TestView</span><span class="token punctuation">(</span>request<span class="token punctuation">)</span><span class="token punctuation">:</span> data <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token string">"user"</span><span class="token punctuation">:</span> <span class="token string">"jack"</span><span class="token punctuation">,</span> <span class="token string">"pwd"</span><span class="token punctuation">:</span> <span class="token string">"123"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> request<span class="token punctuation">.</span>method <span class="token operator">==</span> <span class="token string">'GET'</span><span class="token punctuation">:</span> <span class="token keyword">return</span> HttpResponse<span class="token punctuation">(</span>json<span class="token punctuation">.</span>dumps<span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">,</span>content_type<span class="token operator">=</span><span class="token string">'application/json'</span><span class="token punctuation">)</span> <span class="token keyword">if</span> request<span class="token punctuation">.</span>method <span class="token operator">==</span> <span class="token string">'POST'</span><span class="token punctuation">:</span> <span class="token keyword">return</span> HttpResponse<span class="token punctuation">(</span>json<span class="token punctuation">.</span>dumps<span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">,</span>content_type<span class="token operator">=</span><span class="token string">'application/json'</span><span class="token punctuation">)</span> </code></pre><pre><code class="prism language-python"> MIDDLEWARE <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token string">'django.middleware.common.CommonMiddleware'</span><span class="token punctuation">,</span></p> <pre><code><span class="token string">'django.contrib.auth.middleware.AuthenticationMiddleware'</span><span class="token punctuation">,</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> </code></pre> <p><span class="token punctuation">]</span> </code></pre><blockquote><p>详细了解csrf:https://juejin.cn/post/6844903653757698062.</p></blockquote><h3><a id="312__130"></a>3.1.2 复杂请求处理</h3><p>复杂请求是那种对服务器有特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是<code>application/json</code>。</p><p>复杂请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"(OPTIONS)请求(preflight)。<br>浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。</p><p><strong>PUT方法测试</strong></p><ol><li>修改前端代码<code> method: 'put'</code>发送一个put请求过去。<br>当发送<code>put</code>请求时,先送过来的是一个<code>options</code>请求,浏览器数据请求失败了,我们需要先在<code>options</code>请求的<code>headers</code>中添加<code>Access-Control-Allow-Origin</code><br><img src="https://img-blog.csdnimg.cn/70dbfe4a67d0480b9c8f4c22d2774692.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAUmkwbg==,size_20,color_FFFFFF,t_70,g_se,x_16"></li><li>后端增加一个options判断,并添加<code>Access-Control-Allow-Origin</code></li></ol><pre><code class="prism language-python"> <span class="token keyword">if</span> request<span class="token punctuation">.</span>method <span class="token operator">==</span> <span class="token string">'OPTIONS'</span><span class="token punctuation">:</span> <span class="token keyword">return</span> HttpResponse<span class="token punctuation">(</span>headers<span class="token operator">=</span><span class="token punctuation">{</span><span class="token string">"Access-Control-Allow-Origin"</span><span class="token punctuation">:</span><span class="token string">"<em>"</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token keyword">if</span> request<span class="token punctuation">.</span>method <span class="token operator">==</span> <span class="token string">'PUT'</span><span class="token punctuation">:</span> <span class="token keyword">return</span> HttpResponse<span class="token punctuation">(</span>json<span class="token punctuation">.</span>dumps<span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> </code></pre><ol><li>此时浏览器返回没有<code>Access-Control-Allow-Methods</code> ,表示PUT方法不被允许。我们在<code>PUT和OPTIONS的headers</code>中都再添加一个<code>Access-Control-Allow-Methods</code> ,然后前端继续发送PUT<br><img src="https://img-blog.csdnimg.cn/258bf3c9bc8d449d87a309c036caed8e.png"></li><li>添加了<code>Access-Control-Allow-Methods</code></li></ol><pre><code class="prism language-python"> <span class="token keyword">if</span> request<span class="token punctuation">.</span>method <span class="token operator">==</span> <span class="token string">'OPTIONS'</span><span class="token punctuation">:</span> <span class="token keyword">return</span> HttpResponse<span class="token punctuation">(</span>headers<span class="token operator">=</span><span class="token punctuation">{</span><span class="token string">"Access-Control-Allow-Origin"</span><span class="token punctuation">:</span><span class="token string">"</em>"</span><span class="token punctuation">,</span><span class="token string">"Access-Control-Allow-Methods"</span><span class="token punctuation">:</span><span class="token string">"PUT"</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token keyword">if</span> request<span class="token punctuation">.</span>method <span class="token operator">==</span> <span class="token string">'PUT'</span><span class="token punctuation">:</span> <span class="token keyword">return</span> HttpResponse<span class="token punctuation">(</span>json<span class="token punctuation">.</span>dumps<span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">,</span>headers<span class="token operator">=</span><span class="token punctuation">{</span><span class="token string">"Access-Control-Allow-Origin"</span><span class="token punctuation">:</span><span class="token string">"<em>"</span><span class="token punctuation">,</span><span class="token string">"Access-Control-Allow-Methods"</span><span class="token punctuation">:</span><span class="token string">"PUT"</span><span class="token punctuation">}</span><span class="token punctuation">)</span> </code></pre><ol><li>前端数据获取成功了<br><img src="https://img-blog.csdnimg.cn/18260d7af15b42998feb6428388a4c15.png"></li></ol><p><strong>JSON数据测试</strong><br>前端携带一个json数据,向后端发送post请求,因为Content-Type中不包含JSON格式的数据,所以该请求为复杂请求<br>6. 前端携带JSON数据</p><pre><code class="prism language-js"><span class="token function">Send</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token function">axios</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">method</span><span class="token operator">:</span> <span class="token string">'post'</span><span class="token punctuation">,</span> <span class="token literal-property property">url</span><span class="token operator">:</span> <span class="token string">'http://127.0.0.1:8000/api/test/'</span><span class="token punctuation">,</span> <span class="token literal-property property">data</span><span class="token operator">:</span><span class="token punctuation">{</span> <span class="token string-property property">"course_id"</span><span class="token operator">:</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string-property property">"course_title"</span><span class="token operator">:</span><span class="token string">"中华上下五千年深度解说"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">response</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>response<span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> </code></pre><ol><li>后端接收</li></ol><pre><code class="prism language-python"><span class="token keyword">def</span> <span class="token function">TestView</span><span class="token punctuation">(</span>request<span class="token punctuation">)</span><span class="token punctuation">:</span> data <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token string">"user"</span><span class="token punctuation">:</span> <span class="token string">"jack"</span><span class="token punctuation">,</span> <span class="token string">"pwd"</span><span class="token punctuation">:</span> <span class="token string">"123"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token keyword">print</span><span class="token punctuation">(</span>request<span class="token punctuation">.</span>method<span class="token punctuation">)</span> <span class="token keyword">if</span> request<span class="token punctuation">.</span>method <span class="token operator">==</span> <span class="token string">'GET'</span><span class="token punctuation">:</span> <span class="token keyword">return</span> HttpResponse<span class="token punctuation">(</span>json<span class="token punctuation">.</span>dumps<span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">if</span> request<span class="token punctuation">.</span>method <span class="token operator">==</span> <span class="token string">'POST'</span><span class="token punctuation">:</span> <span class="token keyword">return</span> HttpResponse<span class="token punctuation">(</span>json<span class="token punctuation">.</span>dumps<span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">if</span> request<span class="token punctuation">.</span>method <span class="token operator">==</span> <span class="token string">'OPTIONS'</span><span class="token punctuation">:</span> <span class="token keyword">return</span> HttpResponse<span class="token punctuation">(</span>headers<span class="token operator">=</span><span class="token punctuation">{</span><span class="token string">"Access-Control-Allow-Origin"</span><span class="token punctuation">:</span><span class="token string">"</em>"</span><span class="token punctuation">,</span><span class="token string">"Access-Control-Allow-Methods"</span><span class="token punctuation">:</span><span class="token string">"PUT"</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token keyword">if</span> request<span class="token punctuation">.</span>method <span class="token operator">==</span> <span class="token string">'PUT'</span><span class="token punctuation">:</span> <span class="token keyword">return</span> HttpResponse<span class="token punctuation">(</span>json<span class="token punctuation">.</span>dumps<span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">,</span>headers<span class="token operator">=</span><span class="token punctuation">{</span><span class="token string">"Access-Control-Allow-Origin"</span><span class="token punctuation">:</span><span class="token string">"<em>"</span><span class="token punctuation">,</span><span class="token string">"Access-Control-Allow-Methods"</span><span class="token punctuation">:</span><span class="token string">"PUT"</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token keyword">return</span> HttpResponse<span class="token punctuation">(</span><span class="token string">"okokok"</span><span class="token punctuation">)</span> </code></pre><ol><li>此时,浏览器提示我们需要添加<code>Access-Control-Allow-Headers</code><br><img src="https://img-blog.csdnimg.cn/c92dbbf3db2a4d4881e109d3b58dab46.png"></li><li>我们在POST和OPTIONS中都添加上去,浏览器数据接收成功了</li></ol><pre><code class="prism language-python"><span class="token keyword">if</span> request<span class="token punctuation">.</span>method <span class="token operator">==</span> <span class="token string">'POST'</span><span class="token punctuation">:</span> <span class="token keyword">return</span> HttpResponse<span class="token punctuation">(</span>json<span class="token punctuation">.</span>dumps<span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">,</span>headers<span class="token operator">=</span><span class="token punctuation">{</span><span class="token string">"Access-Control-Allow-Origin"</span><span class="token punctuation">:</span><span class="token string">"</em>"</span><span class="token punctuation">,</span><span class="token string">"Access-Control-Allow-Methods"</span><span class="token punctuation">:</span><span class="token string">"PUT"</span><span class="token punctuation">,</span><span class="token string">"Access-Control-Allow-Headers"</span><span class="token punctuation">:</span><span class="token string">"content-type"</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token keyword">if</span> request<span class="token punctuation">.</span>method <span class="token operator">==</span> <span class="token string">'OPTIONS'</span><span class="token punctuation">:</span> <span class="token keyword">return</span> HttpResponse<span class="token punctuation">(</span>headers<span class="token operator">=</span><span class="token punctuation">{</span><span class="token string">"Access-Control-Allow-Origin"</span><span class="token punctuation">:</span><span class="token string">"*"</span><span class="token punctuation">,</span><span class="token string">"Access-Control-Allow-Methods"</span><span class="token punctuation">:</span><span class="token string">"PUT"</span><span class="token punctuation">,</span><span class="token string">"Access-Control-Allow-Headers"</span><span class="token punctuation">:</span><span class="token string">"content-type"</span><span class="token punctuation">}</span><span class="token punctuation">)</span> </code></pre><p><img src="https://img-blog.csdnimg.cn/50c45fab15f64bee9e3555a78f292fe7.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAUmkwbg==,size_20,color_FFFFFF,t_70,g_se,x_16"></p><h2><a id="32__208"></a>3.2 定义中间件来处理跨域问题</h2><p>在上述的函数中,通过定义headers来处理跨域的多种情况,过于繁琐。我们可以写一个中间件来统一处理跨域问题<br><strong>1.创建CorsMiddleware.py</strong></p><pre><code class="prism language-python"><span class="token keyword">from</span> django<span class="token punctuation">.</span>utils<span class="token punctuation">.</span>deprecation <span class="token keyword">import</span> MiddlewareMixin</p> <p><span class="token keyword">class</span> <span class="token class-name">CorsMiddleware</span><span class="token punctuation">(</span>MiddlewareMixin<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">def</span> <span class="token function">process_response</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span> request<span class="token punctuation">,</span> response<span class="token punctuation">)</span><span class="token punctuation">:</span> response<span class="token punctuation">[</span><span class="token string">"Access-Control-Allow-Origin"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"*"</span> <span class="token keyword">if</span> request<span class="token punctuation">.</span>method <span class="token operator">==</span> <span class="token string">"OPTIONS"</span><span class="token punctuation">:</span> response<span class="token punctuation">[</span><span class="token string">"Access-Control-Allow-Headers"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"Content-Type"</span> response<span class="token punctuation">[</span><span class="token string">"Access-Control-Allow-Methods"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"DELETE, PUT, POST"</span> <span class="token keyword">return</span> response </code></pre><p><strong>2.在Settings.py 配置文件的中间件中添加</strong></p><pre><code class="prism language-python">MIDDLEWARE <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token string">'django.middleware.clickjacking.XFrameOptionsMiddleware'</span><span class="token punctuation">,</span> <span class="token string">'GOMusicApi.utils.cors_middleware.CorsMiddleware'</span><span class="token punctuation">,</span> <span class="token punctuation">]</span> </code></pre><p><strong>3. 重新书写视图,去掉所有的headers,重启项目</strong></p><pre><code class="prism language-python"> <span class="token keyword">from</span> django<span class="token punctuation">.</span>http <span class="token keyword">import</span> JsonResponse<span class="token punctuation">,</span>HttpResponse <span class="token keyword">from</span> rest_framework<span class="token punctuation">.</span>views <span class="token keyword">import</span> APIView <span class="token keyword">class</span> <span class="token class-name">TestView</span><span class="token punctuation">(</span>APIView<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">def</span> <span class="token function">post</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span>request<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">print</span><span class="token punctuation">(</span>request<span class="token punctuation">.</span>body<span class="token punctuation">.</span>decode<span class="token punctuation">(</span><span class="token string">'utf-8'</span><span class="token punctuation">)</span><span class="token punctuation">)</span> data <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token string">"user"</span><span class="token punctuation">:</span> <span class="token string">"jack"</span><span class="token punctuation">,</span> <span class="token string">"password"</span><span class="token punctuation">:</span> <span class="token string">"12333"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> JsonResponse<span class="token punctuation">(</span>data<span class="token punctuation">,</span>safe<span class="token operator">=</span><span class="token boolean">False</span><span class="token punctuation">)</span></p> <p><span class="token keyword">def</span> <span class="token function">TestView</span><span class="token punctuation">(</span>request<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">print</span><span class="token punctuation">(</span>request<span class="token punctuation">.</span>method<span class="token punctuation">)</span> <span class="token keyword">if</span> request<span class="token punctuation">.</span>method <span class="token operator">==</span> <span class="token string">'POST'</span><span class="token punctuation">:</span> <span class="token keyword">print</span><span class="token punctuation">(</span>request<span class="token punctuation">.</span>body<span class="token punctuation">.</span>decode<span class="token punctuation">(</span><span class="token string">'utf-8'</span><span class="token punctuation">)</span><span class="token punctuation">)</span> data <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token string">"user"</span><span class="token punctuation">:</span> <span class="token string">"jack"</span><span class="token punctuation">,</span> <span class="token string">"password"</span><span class="token punctuation">:</span> <span class="token string">"12333"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> JsonResponse<span class="token punctuation">(</span>data<span class="token punctuation">,</span>safe<span class="token operator">=</span><span class="token boolean">False</span><span class="token punctuation">)</span> <span class="token keyword">return</span> JsonResponse<span class="token punctuation">(</span>data<span class="token punctuation">,</span>safe<span class="token operator">=</span><span class="token boolean">False</span><span class="token punctuation">)</span></p> <p></code></pre><p><img src="https://img-blog.csdnimg.cn/d766acb446a44f4286f418610b95577a.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAUmkwbg==,size_20,color_FFFFFF,t_70,g_se,x_16"></p><h2>3.3 使用Django-cors-Headers 来处理跨域问题</h2><p><strong>1. 安装</strong></p><pre><code class="prism language-python">pip install django<span class="token operator">-</span>cors<span class="token operator">-</span>headers </code></pre><p><strong>2. 在settings文件中进行配置</strong></p><pre><code class="prism language-python">INSTALLED_APPS <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token string">'django.contrib.staticfiles'</span><span class="token punctuation">,</span> <span class="token string">'corsheaders'</span><span class="token punctuation">,</span> <span class="token punctuation">]</span></p> <p>MIDDLEWARE_CLASSES <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token string">'corsheaders.middleware.CorsMiddleware'</span><span class="token punctuation">,</span> <span class="token string">'django.middleware.common.CommonMiddleware'</span><span class="token punctuation">,</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">]</span> </code></pre><p><strong>3. Django-cors-Headers 配置介绍</strong><br>在 Django 设置中配置中间件的行为。您必须至少设置以下<strong>三个设置之一</strong>:</p><pre><code class="prism language-python">CORS_ALLOWED_ORIGINS CORS_ALLOWED_ORIGIN_REGEXES CORS_ALLOW_ALL_ORIGINS </code></pre><ul><li><p><code>CORS_ALLOWED_ORIGINS</code></p><pre><code class="prism language-python">CORS_ALLOWED_ORIGINS <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token string">"https://example.com"</span> <span class="token punctuation">,</span> <span class="token string">"https://sub.example.com"</span> <span class="token punctuation">,</span> <span class="token string">"http://localhost:8080"</span> <span class="token punctuation">,</span> <span class="token string">"http://127.0.0.1:9000"</span> <span class="token punctuation">,</span> <span class="token punctuation">]</span> </code></pre></li></ul><p>以前此设置称为<code>CORS_ORIGIN_WHITELIST</code>,它仍然作为别名使用,新名称优先 【注意是django3.2使用新名称】</p><ul><li><p><code>CORS_ALLOWED_ORIGIN_REGEXES</code><br>一个字符串列表,表示与授权进行跨站点 HTTP 请求的 Origin 匹配的正则表达式。默认为[]。当 <code>CORS_ALLOWED_ORIGINS</code>不切实际时很有用,例如当您有大量子域时。</p><pre><code class="prism language-python">CORS_ALLOWED_ORIGIN_REGEXES <span class="token operator">=</span> <span class="token punctuation">[</span> r <span class="token string">"^https://\w+.example.com$"</span> <span class="token punctuation">,</span> <span class="token punctuation">]</span> </code></pre></li></ul><p>以前此设置称为<code>CORS_ORIGIN_REGEX_WHITELIST</code>,它仍然作为别名使用,新名称优先。【注意是django3.2使用新名称】</p><ul><li><code>CORS_ALLOW_ALL_ORIGINS</code><br>如果True,将允许所有来源。其他限制允许来源的设置将被忽略。默认为False。<br>将此设置为True可能很危险,因为它允许任何网站向您的网站发出跨域请求。通常,您需要使用<code>CORS_ALLOWED_ORIGINS</code>或 <code>CORS_ALLOWED_ORIGIN_REGEXES</code>限制允许的来源列表。</li></ul><p>以前此设置称为<code>CORS_ORIGIN_ALLOW_ALL</code>,它仍然作为别名使用,新名称优先。【注意是django3.2使用新名称】</p><p>这下面都是一些<strong>可选设置</strong>了,代码块中为默认值,一般默认值足够了</p><ul><li><p><code>CORS_ALLOW_METHODS</code><br>实际请求允许的 HTTP 动词列表</p><pre><code class="prism language-python">CORS_ALLOW_METHODS <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token string">"DELETE"</span> <span class="token punctuation">,</span> <span class="token string">"GET"</span> <span class="token punctuation">,</span> <span class="token string">"OPTIONS"</span> <span class="token punctuation">,</span> <span class="token string">"PATCH"</span> <span class="token punctuation">,</span> <span class="token string">"POST"</span> <span class="token punctuation">,</span> <span class="token string">"PUT"</span> <span class="token punctuation">,</span> <span class="token punctuation">]</span> </code></pre></li><li><p><code>CORS_ALLOW_HEADERS</code><br>发出实际请求时可以使用的非标准 HTTP 标头列表。</p><pre><code class="prism language-python">CORS_ALLOW_HEADERS <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token string">"accept"</span> <span class="token punctuation">,</span> <span class="token string">"accept-encoding"</span> <span class="token punctuation">,</span> <span class="token string">"authorization"</span> <span class="token punctuation">,</span> <span class="token string">"content-type"</span> <span class="token punctuation">,</span> <span class="token string">"dnt"</span> <span class="token punctuation">,</span> <span class="token string">"origin"</span> <span class="token punctuation">,</span> <span class="token string">"user-agent"</span> <span class="token punctuation">,</span> <span class="token string">"x-csrftoken"</span> <span class="token punctuation">,</span> <span class="token string">"x-requested-with"</span> <span class="token punctuation">,</span> <span class="token punctuation">]</span> </code></pre><ul><li><code>CORS_ALLOW_CREDENTIALS</code><br>如果为<code>True</code>,cookie 将被允许包含在跨站点 HTTP 请求中。默认为False。</li></ul></li></ul><p>注意:在 Django 2.1 中添加了SESSION_COOKIE_SAMESITE设置,默认设置为 "Lax",这将阻止 Django 的会话 cookie 跨域发送。将其更改为无以绕过此安全限制。</p><blockquote><p>详情链接:https://pypi.org/project/django-cors-headers/</p></blockquote><p><strong>4. 我的配置</strong></p><pre><code class="prism language-python"> CORS_ALLOW_CREDENTIALS <span class="token operator">=</span> <span class="token boolean">True</span></p> <p>CORS_ORIGIN_WHITELIST <span class="token operator">=</span> <span class="token punctuation">(</span> <span class="token string">'http://127.0.0.1:8000'</span><span class="token punctuation">,</span> <span class="token string">'http://localhost:8000'</span><span class="token punctuation">,</span> <span class="token string">'http://192.168.1.107:8080'</span> <span class="token punctuation">)</span></p> <p>CORS_ALLOW_METHODS <span class="token operator">=</span> <span class="token punctuation">(</span> <span class="token string">'DELETE'</span><span class="token punctuation">,</span> <span class="token string">'GET'</span><span class="token punctuation">,</span> <span class="token string">'OPTIONS'</span><span class="token punctuation">,</span> <span class="token string">'PATCH'</span><span class="token punctuation">,</span> <span class="token string">'POST'</span><span class="token punctuation">,</span> <span class="token string">'PUT'</span><span class="token punctuation">,</span> <span class="token string">'VIEW'</span><span class="token punctuation">,</span> <span class="token punctuation">)</span></p> <p>CORS_ALLOW_HEADERS <span class="token operator">=</span> <span class="token punctuation">(</span> <span class="token string">'XMLHttpRequest'</span><span class="token punctuation">,</span> <span class="token string">'X_FILENAME'</span><span class="token punctuation">,</span> <span class="token string">'accept-encoding'</span><span class="token punctuation">,</span> <span class="token string">'authorization'</span><span class="token punctuation">,</span> <span class="token string">'content-type'</span><span class="token punctuation">,</span> <span class="token string">'dnt'</span><span class="token punctuation">,</span> <span class="token string">'origin'</span><span class="token punctuation">,</span> <span class="token string">'user-agent'</span><span class="token punctuation">,</span> <span class="token string">'x-csrftoken'</span><span class="token punctuation">,</span> <span class="token string">'x-requested-with'</span><span class="token punctuation">,</span> <span class="token string">'Pragma'</span><span class="token punctuation">,</span> <span class="token punctuation">)</span></p> <p></code></pre><p>配置成功后,前端可以成功访问后端。</p><h2><a id="34__397"></a>3.4 总结</h2><p>浏览器对不同域之间做出的行为,对应不同的请求(简单请求和复杂请求)做出了不同的拦截方式,也就解释了为什么要添加请求参数。<br><code>Access-Control-Allow-Origin </code> :为了解决域不一致的问题;<br><code>Access-Control-Allow-Methods</code> :为了解决PUT,DELETE等方法<br><code>Access-Control-Allow-Headers</code>:为了解决JSON数据传输的问题</p></script>

Original: https://blog.csdn.net/m0_56966142/article/details/123517454
Author: Ri0n
Title: Django 多方式实现跨域访问

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/734154/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球