对于想要利用django框架实现前后端分离,首要的问题是解决跨域请求的问题,什么是跨域请求?简单来说就是当前发起的请求的域与该请求指向的资源所在的域不一致。当协议+域名+端口号均相同,那么就是同一个域.

跨域问题

CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。

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

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

  

  浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。

  只要同时满足以下两大条件,就属于简单请求。

(1) 请求方法是以下三种方法之一:(也就是说如果你的请求方法是什么put、delete等肯定是非简单请求)
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,也就是说,如果你发送的application/json格式的数据,那么肯定是非简单请求,vue的axios默认的请求体信息格式是json的,ajax默认是urlencoded的。

  

* 简单请求和非简单请求的区别?

   简单请求:一次请求
非简单请求:两次请求,在发送数据之前会先发一次请求用于做“预检”,只有“预检”通过后才再发送一次请求用于数据传输。
* 关于“预检” - 请求方式:OPTIONS
- “预检”其实做检查,检查如果通过则允许传输数据,检查不通过则不再发送真正想要发送的消息
- 如何“预检”
=> 如果复杂请求是PUT等请求,则服务端需要设置允许某请求,否则“预检”不通过
Access-Control-Request-Method
=> 如果复杂请求设置了请求头,则服务端需要设置允许某请求头,否则“预检”不通过
Access-Control-Request-Headers

  

报错信息:

解决方案

1.JSONP,比较原始的方法,本质上是利用html的一些不受同源策略影响的标签,例如:<a>,<img>,<iframe>,<script>等,从而实现跨域请求,但是这种方法只支持GET的请求方式。
2.CORS,Cross-Origin Resource Sharing,是一个新的W3C标准,它新增的一组HTTP首部字段,允许服务端声明哪些源站有权限访问哪些资源,换言之,它允许浏览器向声明了CORS的跨域服务器发出XML HttpRequest请求,从而客服Ajax只能同源使用的限制。在django框架中就是利用CORS来解决跨域请求的问题.

1.安装:  pip install django-cors-headers 

2.修改django项目中的settings.py

 INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'corsheaders',#这是我们的主角,放在新建的其他项目之前
'app01',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware', #注意顺序,必须放在这儿
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
] CORS_ALLOW_CREDENTIALS = True CORS_ORIGIN_ALLOW_ALL = True # 允许所有的请求头 CORS_ALLOW_HEADERS = (' * ')

方式一:settings.py

 INSTALLED_APPS = [
...
'corsheaders',
...
] MIDDLEWARE_CLASSES = (
...
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware', # 注意顺序
...
)
#跨域增加忽略
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
CORS_ORIGIN_WHITELIST = (
'*'
) 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',
)

方式二:settings.py

其他解决方案

 使用Ajax获取json数据时,存在跨域的限制。不过,在Web页面上调用js的script脚本文件时却不受跨域的影响,JSONP就是利用这个来实现跨域的传输。因此,我们需要将Ajax调用中的dataType从JSON改为JSONP(相应的API也需要支持JSONP)格式。
JSONP只能用于GET请求。

1.使用JSONP

 修改views.py中对应API的实现函数,允许其他域通过Ajax请求数据:
def myview(_request):
response = HttpResponse(json.dumps({“key”: “value”, “key2”: “value”}))
response[“Access-Control-Allow-Origin”] = “*”
response[“Access-Control-Allow-Methods”] = “POST, GET, OPTIONS”
response[“Access-Control-Max-Age”] = “1000”
response[“Access-Control-Allow-Headers”] = “*”
return response

2.response中间件或者views.py中的API设置

3.中间件解决

  在app下创建一个文件,在其中写如下代码:

接着在settings.py中注册自定义的中间件:

django之CORS跨域请求的更多相关文章

  1. 4 伪ajax:jsonp、cors 跨域请求

    一.同源策略 https://www.cnblogs.com/yuanchenqi/articles/7638956.html 同源策略(Same origin policy)是一种约定,它是浏览器最 ...

  2. Django框架 之 跨域请求伪造

    Django框架 之 跨域请求伪造 浏览目录 同源策略与Jsonp 同源策略 Jsonp jQuery对JSONP的实现 CORS 简介 两种请求 同源策略与Jsonp 同源策略 同源策略(Same ...

  3. Spring Boot Web应用开发 CORS 跨域请求支持:

    Spring Boot Web应用开发 CORS 跨域请求支持: 一.Web开发经常会遇到跨域问题,解决方案有:jsonp,iframe,CORS等等CORS与JSONP相比 1. JSONP只能实现 ...

  4. CORS跨域请求总结

    CORS跨域请求分为简单请求和复杂请求. 1. 简单请求: 满足一下两个条件的请求. (1) 请求方法是以下三种方法之一: HEAD GET POST (2)HTTP的头信息不超出以下几种字段: Ac ...

  5. CORS跨域请求规则以及在Spring中的实现

    CORS: 通常情况下浏览器禁止AJAX从外部获取资源,因此就衍生了CORS这一标准体系,来实现跨域请求. CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origi ...

  6. 记一次 CORS 跨域请求出现 OPTIONS 请求的问题及解决方法

    今天前后端在联调接口的时候,发生了跨域请求资源获取不到的问题. 首先说明下跨域问题的由来.引自HTTP 访问控制 的一段话: 当 Web 资源请求由其它域名或端口提供的资源时,会发起跨域 HTTP 请 ...

  7. 【Django】实现跨域请求

    目录 JsonP实现跨域 在Django中间件中添加响应头 @ *** CORS 即 Cross Origin Resource Sharing 跨域资源共享. 跨域请求分两种:简单请求.复杂请求. ...

  8. Java实现CORS跨域请求

    问题 使用前后端分离模式开发项目时,往往会遇到这样一个问题 -- 无法跨域获取服务端数据 这是由于浏览器的同源策略导致的,目的是为了安全.在前后端分离开发模式备受青睐的今天,前端和后台项目往往会在不同 ...

  9. CORS——跨域请求那些事儿

    在日常的项目开发时会不可避免的需要进行跨域操作,而在实际进行跨域请求时,经常会遇到类似 No 'Access-Control-Allow-Origin' header is present on th ...

随机推荐

  1. C# 基础知识系列- 14 IO篇 文件的操作

    0. 前言 本章节是IO篇的第二集,我们在上一篇中介绍了C#中IO的基本概念和一些基本方法,接下来我们介绍一下操作文件的方法.在编程的世界中,操作文件是一个很重要的技能. 1. 文件.目录和路径 在开 ...

  2. MyBatis配置项--配置环境(environments)--数据源(dataSource)

    数据源(dataSource) dataSource元素使用标准的JDBC数据源接口来配置JDBC连接对象的资源. ·许多MyBatis的应用程序会按示例中的例子来配置数据源.虽然是可选的,但为了使用 ...

  3. CSS开发技巧(三):图片点击缩放

    前言  利用CSS实现图片的点击缩放是一个很值得研究的效果.在某些业务需求场景中,我们可能并没有足够的空间展示过大的图片,这就需要限制图片容器的宽度和高度.然而图片限制了宽度,一些图片的细节便又无法看 ...

  4. CCF NOI1039 2的n次方

    问题链接:CCF NOI1039 2的n次方. 时间限制: 1000 ms  空间限制: 262144 KB 题目描述 对于任意给定的n,计算2的n次方. 输入 输入整数n. 输出 输出2的n次方的值 ...

  5. 《Splunk智能运维实战》——1.7 为本书加载样本数据

    本节书摘来自华章计算机<Splunk智能运维实战>一书中的第1章,第1.7节,作者 [美]乔史·戴昆(Josh Diakun),保罗R.约翰逊(Paul R. Johnson),德莱克·默 ...

  6. Bomb Enemy 炸弹人

    Given a 2D grid, each cell is either a wall 'W', an enemy 'E' or empty '0' (the number zero), return ...

  7. springboot打包启动时报mybatis的typeAlias类名找不到的错误

    springBoot项目在IDEA上面正常但是打包之后运行 出错,错误大致为mybatis解析Mapper.xml时 typeAlias找不到XX类 Mapper里面的标签: <select p ...

  8. N - 寿司晚宴 HYSBZ - 4197 状压dp

    N - 寿司晚宴 HYSBZ - 4197 推荐题解 这个题目我觉得还是很难的,借助题解写出来的,题解还看了很久,现在还是不是很理解. 首先这个数比较大有500,如果直接就像这个题目S - Query ...

  9. php报错:strip_tags() expects parameter 1 to be string, array given

    囧....... 这个表示参数需要字符串,而你传入了数组,所以出错了~ 检查下函数或者方法是否正确,还有参数

  10. Uncaught DOMException: Failed to set the 'value' property on 'HTMLInputElement': This input element accepts a filename, which may only be programmatically set to the empty string.

    今天上传图片遇到这个报错 百度了下,网上说是input标签type=file所以导致的问题,可是我的type=hidden 解决办法: 把上面的代码改成如下问题就解决了