vue-与后端交互--跨域请求
与后端交互
与后端交互统一使用json编码格式
与后端交互涉及到跨越问题和如何处理跨越问题?
当前端发送请求,后端响应了,但是前端还是报错,这是因为:跨域问题的存在,浏览器检测到前端和后端不是来自同一个域,所以认为这是不安全的,所以就拦截了该资源的传递
想要解决这个问题,就要实现:CORS,也就是 跨域资源共享
http://photo.liuqingzheng.top/2023 02 15 18 46 15 /01 get.gif
跨域问题---响应头添加允许headers={'Access-Control-Allow-Origin':'*'}
浏览器的原因,只要不是向地址栏中的【域:地址和端口】发送请求,拿的数据,浏览器就给拦截了。
处理跨域问题
后端代码处理,只需要在响应头中加入允许即可
1. jquery发送ajax
点击查看代码
headers={'Access-Control-Allow-Origin':'*'}
# 访问控制允许的源 设置为全部
# 路由
from django.urls import path,include
from app01 import views
from rest_framework.routers import SimpleRouter
router = SimpleRouter()
router.register('user',views.UserShow,'user')
urlpatterns = [
path('admin/', admin.site.urls),
path('api/v1/',include(router.urls))
]
# 视图类
from rest_framework.viewsets import ViewSetMixin,ViewSet,ModelViewSet
from rest_framework.decorators import action
from rest_framework.response import Response
# 采用CBV
class UserShow(ViewSet):
@action(methods=['GET'],detail=False)
def index(self,request):
print('函数执行了')
return Response(headers={'Access-Control-Allow-Origin':'*'},data={'name':'kiki','age':18,'gender':'female'})
# 页面分离
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
</head>
<body>
<div class="app">
<h1>加载用户信息</h1>
<button @click="handleData">显示数据</button>
<div v-if="age!=0">
<p>用户名:{{ username }}</p>
<p>年龄:{{ age }}</p>
<p>性别:{{ gender }}</p>
</div>
<div v-else>
无用户信息
</div>
</div>
</body>
<script>
var vm = new Vue({
el:'.app',
data:{
username:'',
age:0,
gender:'未知',
},
methods:{
handleData(){
//1 学过的,jq的ajax
$.ajax({
url:'http://127.0.0.1:8000/api/v1/user/index/',
type:'get',
data:[],
success:data=>{
console.log(data)
this.username=data.name
this.age=data.age
this.gender=data.gender
}
})
}
}
})
</script>
</html>
2. fetch发送ajax请求
# fetch 提供了一个 JavaScript 接口,用于访问和操纵 HTTP 管道的一些具体部分,例如请求和响应
-新的发送ajax 接口
-用起来比较方便
-支持promise写法[最新的异步写法]
-解决了原生的XMLHttpRequest兼容性的问题
-不是所有浏览器都支持
-主流现在是用axios[第三方]发送请求
# XMLHttpRequest: 原生js提供的
-比较老,不同浏览器需要做一些兼容性的处理,写起来比较麻烦
-jq基于它做了封装
# 发送ajax请求,
点击查看代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
</head>
<body>
<div class="app">
<h1>加载用户信息</h1>
<button @click="handleData">显示数据</button>
<div v-if="age!=0">
<p>用户名:{{ username }}</p>
<p>年龄:{{ age }}</p>
<p>性别:{{ gender }}</p>
</div>
<div v-else>
无用户信息
</div>
</div>
</body>
<script>
var vm = new Vue({
el:'.app',
data:{
username:'',
age:0,
gender:'未知',
},
methods:{
handleData(){
//1 fetch
fetch('http://127.0.0.1:8000/api/v1/user/index/').then(response=>response).then(res=>{
console.log(res)
console.log('fetch')
this.username=res.name
this.age=res.age
this.gender=res.gender
})
}
}
})
</script>
</html>
3. Axios发送ajax请求
Axios是在Vue框架上,是第三方的模块, Axios 是一个基于 promise 的 HTTP 库,还是基于XMLHttpRequest封装的。
下载第三方模块
pip install axios
Axios发送ajax前后端交互
点击查看代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue.js"></script>
<script src="axios.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
</head>
<body>
<div class="app">
<h1>加载用户信息</h1>
<button @click="handleData">显示数据</button>
<div v-if="age!=0">
<p>用户名:{{ username }}</p>
<p>年龄:{{ age }}</p>
<p>性别:{{ gender }}</p>
</div>
<div v-else>
无用户信息
</div>
</div>
</body>
<script>
var vm = new Vue({
el:'.app',
data:{
username:'',
age:0,
gender:'未知',
},
methods:{
handleData(){
//1 axios
axios.get('http://127.0.0.1:8000/api/v1/user/index/').then(res=>{
console.log(res)
this.username=res.data.name
this.age=res.data.age
this.gender=res.data.gender
})
}
}
})
</script>
</html>

4. 电影--案例
官网:https://m.maizuo.com/v5/#/films/nowPlaying

点击查看代码
# 视图类
class UserShow(ViewSet):
@action(methods=['GET'], detail=False)
def film(self, request):
# 打开文件
with open('./film.json','r',encoding='utf-8')as f:
f= json.load(f)
print(f)
return Response(headers={'Access-Control-Allow-Origin': '*'},
data=f)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue.js"></script>
<script src="axios.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
</head>
<body>
<div class="app">
<h1>最近电影</h1>
<button @click="handleData">显示电影</button>
<ul>
<li v-for=" i in dataList" >
<h2>名字:{{ i.name }}</h2>
<h3>导演:{{ i.director }}</h3>
<h3>类型:{{ i.category }}</h3>
<p>简介:{{ i.synopsis }}</p>
<img :src="i.poster" alt="" height="300px" width="200px">
</li>
</ul>
</div>
</body>
<script>
var vm = new Vue({
el:'.app',
data:{
dataList:[]
},
methods:{
handleData(){
//1 axios
axios.get('http://127.0.0.1:8000/api/v1/user/film/').then(res=>{
console.log(res)
this.dataList=res.data.data.films
console.log(this.date)
})
},
//直接加载
created() {
// this.handleClick()
axios.get('http://127.0.0.1:8000/api/v1/user/film/').then(res => {
this.dataList = res.data.data.films
})
}
}
})
</script>
</html>

跨域请求--CORS两种请求
CORS基本流程
浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。
浏览器发出CORS简单请求,只需要在头信息之中增加一个Origin字段。
浏览器发出CORS非简单请求,会在正式通信之前,增加一次HTTP查询请求,称为”预检”请求(preflight)。浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。
跨域问题详解
前端发送ajax请求,后端会有跨域的拦截,原因是:同源策略。同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。
-请求的url地址,必须与浏览器上的url地址处于同域上,也就是域名,端口,协议相同.
-发送ajax请求的地址,必须跟浏览器上的url地址处于同域上 域[域名,地址,端口,协议]
-请求成功,数据库返回,但是浏览器拦截
# 补充:浏览器中输入域名,没有加端口
-www.baidu.com---->dns--->解析成地址 192.168.2.3----》没有加端口,默认是80
-dns解析,先找本地的host文件
-可以修改本地的host做映射
如何解决跨域问题?
-
CORS:后端代码控制,咱们采用的方式
# cors: #xss,csrf---跨站请求伪造 跨域资源共享:后端技术,就是在响应头中加入 固定的头,就会运行前端访问了 # CORS基本流程 浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。 浏览器发出CORS简单请求,只需要在头信息之中增加一个Origin字段。 浏览器发出CORS非简单请求,会在正式通信之前,增加一次HTTP查询请求,称为”预检”请求(preflight)。浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错 # 什么是简单请求,什么是非简单请求 # 符合如下条件,就是简单请求 (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 # 演示简单和非简单请求 -如果是简单,直接发送真正的请求 -如果是非简单,先发送options,如果运行,再发真正的第一种方式---后端添加请求头
# 前端发送axios不添加请求头---简单请求 created() { this.$axios.get(this.$settings.BASE_URL+ '/home/banner/').then(res=>{ console.log(res) }) }, # 允许的前端地址 return APIResponse(data=res.data, headers={ "Access-Control-Allow-Origin": "http://192.168.1.47:8080"}) # {code:100,msg:成功,data=[{},{}]} # 允许所有前端地址 return APIResponse(data=res.data,headers={'Access-Control-Allow-Origin':'*'}) # {code:100,msg:成功,data=[{},{}]}第二种方式---书写中间件
解决跨域问题和请求头携带数据
# 1.重写process_response方法 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 # 2. 注册中间件 MIDDLEWARE = [ 'utils.common_middle.CorsMiddleWare' ]**第三种方式---第三方模块django-cors-headers **
# 第一步:安装 pip install django-cors-headers # 第二步:配置app INSTALLED_APPS = [ 'corsheaders' ] # 第三步:配置中间件 MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', ] # 第四步:在配置文件配置 # 允许所有域 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', ) -
Nginx反向代理 (常用)
-
JSONP:很老不会用了,它只能发get请求
-
搭建Node代理服务器

浙公网安备 33010602011771号