Luffy - 解决跨域问题

  • 一:跨域请求
    • 0. 跨域问题的出现
    • 1.同源策略
      • ① 简介
    • 2. CORS(跨域资源共享)简介
    • 3. `CORS`基本流程
    • 4. 解决跨域问题的3种方法
    • 5. `CORS`两种请求详解
    • 6. 浏览器对这两种请求的处理,是不一样的
  • 二:解决跨域问题(服务端)
    • 【简单请求】
      • 1. 原Django项目:`apps/user/views.py`
      • 2. 原Django项目:`apps/user/urls.py`
      • 3. 原Django项目:`dev.py`中注释掉`CSRF`
      • 4. 再创建1个Django项目(用另外的端口)
        • ① `templates`中创建`index.html`
        • ② `views.py`
        • ③ `urls.py`
    • 【非简单请求】
      • 原Django项目`apps/user/views.py`
      • 新Django项目`templates/index.html`
    • 【中间件处理】
      • ① 在原Django项目的根路径创建`mymiddle.py` - 自定义中间件
      • ② 在原Django项目的`dev.py`的中间件中添加自定义中间件
      • ③ 原Django项目`apps/user/views`中替换成如下代码
  • 三:解决跨域问题(第三方)
    • 1. 后端配置
      • ① 后端安装跨域模块
      • ② 到`dev.py`中进行注册
      • ③ 到`dev.py`中添加中间件
      • ④ 到`dev.py`中添加如下代码
      • ⑤ 设置`dev.py`的`ALLOWED_HOSTS`
    • 2. 后端测试
      • ① (测试 - 后台)到`apps/user/views`中替换成如下代码
      • ② (测试 - 后台)到apps/user/urls中替换成如下代码
      • ③ 启动项目
      • ④ 访问测试
    • 3. 前端测试
      • ①(测试 - 前台)`App.vue` 中换成如下代码
      • ② 启动项目
    • 4. 测试效果
  • 四:解决跨域问题(前端)
    • 1. 前端`App.vue`
    • 2. 前端项目根路径的`vue.config.js`

一:跨域请求

0. 跨域问题的出现

问题出现:前后端来自同一个IP的不同端口

一种奇葩的解决方法:开发的时候前后端分离,部署的时候不分离

1.同源策略

① 简介

同源策略,是浏览器为了保护用户信息安全的一种安全机制

所谓的同源就是指代通信的两个地址(例如服务端接口地址与浏览器客户端页面地址)之间比较,是否协议、域名(IP)和端口相同

不同源的客户端脚本[javascript]在没有得到服务端的明确授权的情况下,浏览器会拒绝显示服务端信息提供给前端ajax/axios

前端地址:http://www.4399.com/index.html 是否同源 原因
http://www.4399.com/user/login.html 协议、域名、端口相同
http://www.4399.com/about.html 协议、域名、端口相同
https://www.4399.com/user/login.html 协议不同 ( https和http )
http:/www.4399.com:5000/user/login.html 端口 不同( 5000和80)
http://doc.4399.com/user/login.html 域名不同 ( doc和www )
http://www.4399.top/user/login.html 域名不同 ( com和top )

2. CORS(跨域资源共享)简介

CORS是一个W3C标准,全称是"跨域资源共享",它允许浏览器向跨源的后端服务器发出ajax请求,从而克服了AJAX只能同源使用的限制。
实现CORS主要依靠后端服务器中响应数据中设置响应头信息返回的

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

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

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

容易混淆的点:

  • CORS:跨域资源共享
  • CSRF:跨站请求伪造
  • XSS:跨站脚本攻击

3. CORS基本流程

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

  • 浏览器发出CORS简单请求,只需要在头信息之中增加一个Origin字段
  • 浏览器发出CORS非简单请求,会在正式通信之前,增加一次HTTP查询请求,称为”预检”请求(preflight
  • 览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段
  • 只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。

4. 解决跨域问题的3种方法

  • 前端解决(通过代理解决)
  • 自己解决(自己写代码)
  • 借助第三方模块(django-cors-headers

5. CORS两种请求详解

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

  • ① 请求方法是以下三种方法之一

    • HEAD
    • GET
    • POST
  • HTTP的头信息不超出以下几种字段

    • Accept
    • Accept-Language
    • Content-Language
    • Last-Event-ID
    • Content-Type:只限于三个值application/x-www-form-urlencodedmultipart/form-datatext/plain
  • 凡是不同时满足上面两个条件,就属于非简单请求

6. 浏览器对这两种请求的处理,是不一样的

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

  • 简单请求:发1次请求
  • 非简单请求:发2次请求,在发送数据之前会先发1次请求用于做“预检”看后端是否允许,只有“预检”通过后才再发送1次请求用于数据传输。
    请求方式:OPTIONS

预检:

  • 检查如果通过则允许传输数据,检查不通过则不再发送真正想要发送的消息

如何预检:

  • 如果复杂请求是PUT等请求,则服务端需要设置允许某请求,否则“预检”不通过
    Access-Control-Request-Method
  • 如果复杂请求设置了请求头,则服务端需要设置允许某请求头,否则“预检”不通过
    Access-Control-Request-Headers

二:解决跨域问题(服务端)

【简单请求】

1. 原Django项目:apps/user/views.py

from django.http import JsonResponsedef test(request):obj = JsonResponse({'name': 'Darker', 'age': '18'})# 值针对简单请求obj['Access-Control-Allow-Origin'] = '*'    # 允许所有IP访问return obj

2. 原Django项目:apps/user/urls.py

from django.urls import path
from user import viewsurlpatterns = [path('test/', views.test),
]

3. 原Django项目:dev.py中注释掉CSRF

4. 再创建1个Django项目(用另外的端口)

templates中创建index.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<button id="btn">点我</button></body>
<script>$('#btn').click(function () {$.ajax({url: 'http://127.0.0.1:8000/user/test/',method: 'get',success: function (data) {console.log(data)}})})
</script>
</html>

views.py

from django.shortcuts import renderdef index(request):return render(request, 'index.html')

urls.py

from django.urls import path
from app01 import viewsurlpatterns = [path('test/', views.index),
]

【非简单请求】

原Django项目apps/user/views.py

from django.http import JsonResponsedef test(request):obj = JsonResponse({'name': 'Darker', 'age': '18'})if request.method == 'OPTIONS':obj['Access-Control-Allow-Headers'] = 'Content-Type,authorization'  # 或者填写 *obj['Access-Control-Allow-Origin'] = 'http://127.0.0.1:8002'    # 8002端口是当前项目的return obj

新Django项目templates/index.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<button id="btn">点我</button></body>
<script>$('#btn').click(function () {let obj = {name: 'Darker'}$.ajax({url: 'http://127.0.0.1:8000/user/test/',method: 'post',contentType: 'application/json',headers: {authorization: 'Darker'},data: JSON.stringify(obj),success: function (data) {console.log(data)}})})
</script>
</html>

【中间件处理】

① 在原Django项目的根路径创建mymiddle.py - 自定义中间件

from django.utils.deprecation import MiddlewareMixinclass CoreMiddle(MiddlewareMixin):def process_response(self, request, response):if request.method == 'OPTIONS':response['Access-Control-Allow-Headers'] = 'Content-Type, authorization'    # 如果是 * 就代表全部IP都可以访问response['Access-Control-Allow-Origin'] = '*'return response

② 在原Django项目的dev.py的中间件中添加自定义中间件

MIDDLEWARE = ['django.middleware.security.SecurityMiddleware','django.contrib.sessions.middleware.SessionMiddleware','mymiddle.CoreMiddle',    # 这一句'django.middleware.common.CommonMiddleware',# 'django.middleware.csrf.CsrfViewMiddleware','django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware',
]

③ 原Django项目apps/user/views中替换成如下代码

from django.http import JsonResponsedef test(request):return JsonResponse({'name': 'Darker', 'age': '18'})

三:解决跨域问题(第三方)

1. 后端配置

① 后端安装跨域模块

pip install django-cors-headers

② 到dev.py中进行注册

INSTALLED_APPS = (...'corsheaders'
)

③ 到dev.py中添加中间件

MIDDLEWARE = [...'corsheaders.middleware.CorsMiddleware','django.middleware.common.CommonMiddleware',    # 这个是原本就存在的...
]

④ 到dev.py中添加如下代码

CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
# CORS_ORIGIN_WHITELIST = (
#     'http://127.0.0.1:8080',
# )
CORS_ALLOWED_ORIGINS_REGEXES=[r'^http://.*?$',
]
# CORS_ORIGIN_REGEXES_WHITELIST = (
#         r'^http://.*?$',
# )
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',
)

⑤ 设置dev.pyALLOWED_HOSTS

ALLOWED_HOSTS = ['*']

2. 后端测试

① (测试 - 后台)到apps/user/views中替换成如下代码

from django.http import JsonResponsedef test(request):return JsonResponse({'name': 'Darker', 'age': '18'})

② (测试 - 后台)到apps/user/urls中替换成如下代码

from django.urls import path
from user import viewsurlpatterns = [path('test/', views.test),
]

③ 启动项目

python manage.py runserver 127.0.0.1:8000

④ 访问测试

3. 前端测试

①(测试 - 前台)App.vue 中换成如下代码

<template><div id="app"><router-view/>{{name}}</div>
</template><script>
export default {data () {return {name: []}},mounted () {this.$axios.get(this.$settings.base_url + '/user/test/').then(res => {this.name = res.data})}
}
</script>

② 启动项目

npm run serve

4. 测试效果

四:解决跨域问题(前端)

1. 前端App.vue

<template><div id="home"><h1>我是主页</h1><h2>{{info}}</h2></div>
</template><script>
export default {name: 'Home',data () {return {info: []}},mounted () {this.$axios.get('/moreClassicList?sortId=1&showType=3').then(res => {console.log(res.data)})}
}
</script><style scoped></style>

2. 前端项目根路径的vue.config.js

const webpack = require("webpack");module.exports = {configureWebpack: {plugins: [new webpack.ProvidePlugin({$: "jquery",jQuery: "jquery","window.jQuery": "jquery","window.$": "jquery",Popper: ["popper.js", "default"]})]},devServer: {proxy: {'/ajax': {target: 'https://m.maoyan.com/',changeOrigin: true},'/user': {target: 'http://127.0.0.1:8000',changeOrigin: true}}}
};

Luffy - 解决跨域问题相关推荐

  1. 继承WebMvcConfigurer 和 WebMvcConfigurerAdapter类依然CORS报错? springboot 两种方式稳定解决跨域问题

    继承WebMvcConfigurer 和 WebMvcConfigurerAdapter类依然CORS报错???springboot 两种方式稳定解决跨域问题! 之前我写了一篇文章,来解决CORS报错 ...

  2. CORS-跨域资源共享 解决跨域问题

    1.什么是跨域? a.test.com 和 b.test.com 是两个不同的域,而处于安全机制考虑,JS只能访问与所在页面同一个域(相同协议.域名.端口)的内容,但是我们在项目开发时,经常遇到一个页 ...

  3. 前端解决跨域问题的8种方案(最新最全)

    .同源策略如下: URL 说明 是否允许通信 http://www.a.com/a.js http://www.a.com/b.js 同一域名下 允许 http://www.a.com/lab/a.j ...

  4. React Axios 请求解决跨域问题

    网上看了很多的方案,但是不知道为什么,作为初学者,对react不太清楚的话,解决跨域还是有很多的问题.这篇博客针对小白,第一次调试react 跨域问题,甚至第一次使用Axios ,第一次... 废话就 ...

  5. iframe解决跨域ajax请求的方法

    iframe跨域的基本前提是,一个页面可以嵌套非同源站点的html文件,以及某一个域名下的html页面可以通过脚本向同域名服务器发出ajax请求.当一个域名为domain1下的页面A想要向domain ...

  6. java 跨域_springboot解决跨域CROS问题,用注解@CrossOrigin

    项目是springboot框架,前后端分离,需要跨域,当前前端可以用JSONP解决,但是java端如何解决呢? 因为是springboot框架,所以好多都可以用注解解决问题,所以就用到了@CrossO ...

  7. android ajax 跨域更新本地html,本地webapp是怎么解决跨域问题的?

    像ionic的cli,都可以把一个ionic的webapp打包成本地的,那这样的话是如何解决跨域问题的? 在PC上,我直接访问连接获取数据,代码如下.(抄自W3School) function loa ...

  8. jsonp解决跨域问题

    跨域 就是由于JavaScript同源策略的限制,使得a.com域名下的js无法操作b.com或c.a.com域名下的对象或数据. 简单理解同一个域就是:相同域名.相同端口.相同协议! JS部分(使用 ...

  9. axios请求接口http_Vue使用Axios实现http请求以及解决跨域问题

    Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中.Axios的中文文档以及github地址如下: 中文:https://www.kancloud.cn/y ...

最新文章

  1. 黑帽SEO:Google为什么会屏蔽你的网站
  2. 知识图谱学习笔记-知识图谱介绍
  3. java nio.Buffer的属性变化
  4. [自爆系列]浅谈我对搜索的错误了解
  5. Jetson Nano安装pytorch 基于torch1.6和torchvision0.7
  6. BootStrap的入门和响应式的使用
  7. 万字长文:解读区块链7类共识算法
  8. spring boot controller 初始化_基于 tyboot 快速初始化 springboot 单体项目
  9. 架构师要了解那些??
  10. Android 四大组件学习之ContentProvider四
  11. java 验证是否为省份证号 详细验证 验证月份 日期等 要素
  12. 使用wps把word格式文件转换成pdf文件
  13. 2009年25大最新网络游戏排行榜
  14. scrapy15.0,scrapy.contrib.downloadermiddleware.useragent` is deprecated,旧模块被弃用解决办法.
  15. a10 amd 安装黑苹果_黑苹果整合版系统U盘镜像Niresh macOS Sierra 10.12.3 支持Intel/AMD......
  16. Me-tetrazine-Disulfo-Cyanine5,甲基四嗪-磺酸基菁染料Cy5,蓝色固体
  17. 计算机网络知识点————交换机
  18. 如何彻底关闭windows10自动更新,禁用Windows Update
  19. python字典操作题_python字典练习题
  20. 向量、矩阵乘法的几何意义(二) 矩阵乘法(Matrix Multiplication)

热门文章

  1. 异物卡喉应如何正确诊疗
  2. 阿里云IoT启动ID² INSIDE商标授权计划,全生态赋能合作伙伴
  3. 学习SpringBoot 集成mybaties (参考纯洁的微笑) 记录其中遇到的问题
  4. 培训云计算架构师需要学习五件事
  5. Java 线程池原理总结
  6. 一些乱七八糟的短信……
  7. python windows桌面程序开发_Python 零基础入门
  8. 网络流----最小费用最大流(EK+SPFA)
  9. vue中使用bootstrapvue
  10. 【创建数据库表及添加数据】