举个例子开头
前端
配置文件
一个前端vue中的配置,给出三种情况
vue.config.js
proxy: {
'/api/test': { //这里最好有一个 /
target: 'http://192.168.115.115:8888', // 后台接口域名
// ws: true, //如果要代理 websockets,配置这个参数
// secure: false, // 如果是https接口,需要配置这个参数
changeOrigin: true, //是否跨域
pathRewrite: {
'^/api/test': '/api/test'
}
}
}
这种情况的解释就是前端调用的地方(看下面),axios匹配到/api/test的时候,
这里的pathRewrite是和target打配合使用的,就好比英雄联盟里面的ADC和辅助,target+pathRewrite 就是应对/api/test的最终解释。
因此我们就直接找到http://192.168.115.115:8888/api/test 这个后台接口
proxy: {
'/api/test': { //这里最好有一个 /
target: 'http://192.168.115.115:8888/api/test', // 后台接口域名
// ws: true, //如果要代理 websockets,配置这个参数
// secure: false, // 如果是https接口,需要配置这个参数
changeOrigin: true, //是否跨域
pathRewrite: {
'^/api/test': '/'
}
}
}
这种情况的解释就是前端调用的地方(看下面),axios匹配到/api/test的时候,
这里的pathRewrite是和target打配合使用的,就好比英雄联盟里面的ADC和辅助,target+pathRewrite 就是应对/api/test的最终解释。由于pathRewrite为/ ,那么就不会配合出个花样来,因此,为了保证能够够到后台,只能在target中写多一点喽
因此我们就直接找到http://192.168.115.115:8888/api/test 这个后台接口
proxy: {
'/api/test': { //这里最好有一个 /
target: 'http://192.168.115.115:8888/api/test', // 后台接口域名
// ws: true, //如果要代理 websockets,配置这个参数
// secure: false, // 如果是https接口,需要配置这个参数
changeOrigin: true, //是否跨域
pathRewrite: {
'^/api/test': ''
}
}
}
这种情况和上面的一模一样。最终目的都是为了和后台交流好。
当然好奇者也可以关注一下下面几个情况,最后练习有讲解
proxy: {
'/api/test': { //这里最好有一个 /
target: 'http://192.168.115.115:8888/api/test', // 后台接口域名
// ws: true, //如果要代理 websockets,配置这个参数
// secure: false, // 如果是https接口,需要配置这个参数
changeOrigin: true, //是否跨域
pathRewrite: {
'^': ''
}
}
}
proxy: {
'/api/test': { //这里最好有一个 /
target: 'http://192.168.115.115:8888/api/test', // 后台接口域名
// ws: true, //如果要代理 websockets,配置这个参数
// secure: false, // 如果是https接口,需要配置这个参数
changeOrigin: true, //是否跨域
pathRewrite: {
'^': '/'
}
}
}
接口声明
前端中的调用,调用的地方
接口声明文件:
/api/testApi.js
import axios from 'axios'
export function list(params) {
return axios({
url: '/api/test',
method: 'get',
params
})
}
export function fetched(params) {
return axios({
url: '/api/test/' + params,
method: 'get'
})
}
export function updated(data) {
return axios({
url: '/api/test',
method: 'put',
data
})
}
export function created(data) {
return axios({
url: '/api/test',
method: 'post',
data
})
}
export function deleted(data) {
// const { id } = data
return axios({
url: `/api/test/${data}`,
method: 'delete',
// params: data
})
}
直接调用。
(我们这种情况是调用和声明接口分离的情况下,解耦合)
调用文件
hello.vue
<script>
import * as testApi from '@/api/testApi'
import { parseTime } from '@/utils'
import Pagination from '@/components/Pagination'
created() {
this.getData()
},
export default{
methods: {
getData() {
const { total, ...page } = this.pageConfig
const params = { ...page, ...this.searchQuery }
this.loading = true
testApi.list(params).then(response => {
const data = response.data.data
})
},
// 新增
add() {
testApi.created(params).then((response) => {
})
}
})
},
// 删除
handleDelete(row) {
testApi.deleted(id).then(response => {
this.$notify({
title: 'Success',
message: '删除成功',
type: 'success',
duration: 2000
})
this.getData()
})
},
// 编辑
handleEdit(row) {
},
}
}
}
</script>
后台实际的swagger 接口
java
package com..controller;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.api.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.io.IOException;
import java.io.Serializable;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;
import java.util.Set;
@RestController
@RequestMapping("/api/test")
public class TestController extends BaseController {
@GetMapping
public R<IPage<Test>> selectAll() {
}
@GetMapping("/all")
public R<List<Test>> select(String i) {
}
@GetMapping("{id}")
public R<Test> selectOne(@PathVariable Serializable id) {
}
@PostMapping
public R insert(@RequestBody Test t) {
}
@PutMapping
public R<Boolean> update(@RequestBody Test t) {
}
@DeleteMapping("{id}")
public R<Boolean> delete(@PathVariable long id) {
}
@PostMapping("/test")
public R<Boolean> test(@RequestBody Test t)
}
}
谨记
学习这个属性之前,请记住一句话,这个属性就是和后台打交道,和nginx打交道,
和浏览器输入栏中的地址打交道的是一个叫router的东西.这两个东西不是一个玩意,
不要盯着地址栏看,看浏览器F12之后的网络属性那一段,一定要死记住。
后端现在死定住了。
直接在浏览器或者postman上使用
http://192.168.115.115:8888
这个地址前提下可以进行curd的相关操作。
增:http://192.168.115.115:8888/api/test
删:http://192.168.115.115:8888/api/test{id}
改:http://192.168.115.115:8888/api/test
查全部:http://192.168.115.115:8888/api/test
查一个:http://192.168.115.115:8888/api/test/{id}
后端已经定了,前端调用的地方,调用的代称是/api/test.
所以我们调回去看配置文件
总结
1.router(路由)是用来处理跳转的,它管的范围就是浏览器框,讲明白一点就是浏览器上那一个框,那个框的展示就是前端router里控制的
2.pathRewrite,以及它外面的proxy(代理),它管的范围就是浏览器F12中的网络选项。这时就会有人想,这个属性或者proxy这个属性全部,就是看着网络里的地址改变,binggo,对了。所以只要proxy中,代理的地址写好之后,在网络选项那里就看到这个,是固定的。pathRwrite不会影响网络里的地址的展示。
拼了命的拼接出可以正常使用的后台接口。你在F12的网络和地址栏,哪儿都看不到,人家就是和nginx和swagger暧昧,其他的人哪凉快去哪玩
3.nginx中只关心proxy定义的key以及最后拼接出来的后端地址,其他的,全他娘的不管
demo针对文章开头例子
location /api/test {
proxy_pass http://192.168.115.115:8888/api/test;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
}
nginx的配置和前端代理中以及请求中的配置是不能随便写的。
几个练习题:
按照上面的理解这些题应该是下面这样的结果。
前空后空
dev: {
'/api/a': {
target: 'http://192.168.115.115:8000',
changeOrigin: true,
pathRewrite: { '^': '' }, 这种情况和 pathRewrite: { '^': '/' }, 一毛一样
},
拼出来的地址 http://192.168.115.115:8000
前空后不空
'/api/b': {
target: 'http://192.168.115.115:8001',
changeOrigin: true,
pathRewrite: { '^': '/api/b' },
},
拼出来的地址 http://192.168.115.115:8001/api/b,但是这种情况最好不要使用,这是找死,
前不空后空
'/api/c': {
target: 'http://192.168.115.115:8002',
changeOrigin: true,
pathRewrite: { '^/api/c': '' },
},
拼出来的地址 http://192.168.115.115:8002/api/c
前不空后不空
'/api/d': {
target: 'http://192.168.115.115:8003',
ws: true,
changeOrigin: true,
pathRewrite: { '^/api/d': '/api/rest_j/v1' },
},
拼出来的地址 http://192.168.115.115:8001/api/rest_j/v1