修改端口 为了端口不冲突
package.json—— “serve”: “vue-cli-service serve --port=80”,
形成跨域:
- 协议是否一样
- 服务器的ip是否一样
- 端口是否一样
上面三个只要有一个不一样, 形成跨域
//后台服务器 代理服务器解决跨域问题
devServer: {
//后台服务器协议+端口
proxy: {
'/api': {//api替代url
target: 'http://localhost:8888',
ws: false,
changeOrigin:true,//支持跨域请求
}
}
}
发送的请求加 /api前缀
login() {
//前端解决跨域
this.$http.get("/api/vuelogin?user=zhangsan&password=123")
.then(function (response) {
//处理成功情况
console.log(response)
})
.catch(function (error) {
//处理错误情况
console.log(error);
})
}
@WebFilter(filterName = "CrossFilter",urlPatterns = "/*")
public class CrossFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*"); //允许所有的域名访问
response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, PATCH, DELETE"); //允许的提交方式
response.setHeader("Access-Control-Max-Age", "3600"); //最大有效时间
response.setHeader("Access-Control-Allow-Headers", "x-requested-with, Content-Type, Accept, Origin"); //允许那些请求头
response.setHeader("Access-Control-Allow-Credentials", "true"); //是否支持ajax提交cookie
chain.doFilter(req, res);
}
public void init(FilterConfig filterConfig) {}
public void destroy() {}
}
3.使用nginx,其他的服务器处理跨域
实际开发中:确定api文档,统一响应数据格式
验证
// 禁止序列化密码
@JSONField(serialize = false)
private String password;
统一响应数据格式后 前端返回的数据
login(){
//后端解决跨域
var that = this; // 函数内的this指向函数 没有指向data
that.$axios.get("http://localhost:8888/api/vuelogin?user=" + that.username + "&password=" + that.password)
.then(function (response) {
console.log(response)
//处理成功情况
// response.data.meta.status === 200
//1.const res = response.data return res响应拦截器 2. === 数据类型也要相同
if (response.meta.status === 200) {
//保持token到本地
let admin = response.data;
localStorage.setItem("token", admin.username);
//跳转页面
that.$router.push({
name: 'home',
query: {
username: admin.username
}
});
} else {
that.user = "";
that.password = "";
alert(response.meta.msg);
}
})
.catch(function (error) {
//处理错误情况
console.log(error);
alert("服务器出错..")
})
}
跳转页面获取参数
{{username}}
computed: {
username() {
// 函数内加this
return this.$route.query.username;
}
}
问题:post请求 参数不能跟在请求路径后
注意:
axios 发送请求, 使用请求体发送请求参数, 以json形式传递给服务器
request.getParameter("user") //要求请求参数是key/value对的方式
utils.request.js
import axios from 'axios'
import qs from 'qs'
/**
* axios的传参方式:
* 1.url 传参 一般用于Get和Delete 实现方式:config.params={JSON}
* 2.body传参 实现方式:config.data = {JSON},且请求头为:headers: { 'Content-Type': 'application/json;charset=UTF-8' }
* 3.表单传参 实现方式:config.data = qs.stringify({JSON}),且请求头为:且请求头为:headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' }
*/
// axios实例
const $http = axios.create({
baseURL: 'http://localhost:8888/api/',
timeout: 60000,
headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' }
})
// 请求拦截器
$http.interceptors.request.use(
(config) => {
// 追加时间戳,防止GET请求缓存
if (config.method?.toUpperCase() === 'GET') {
config.params = { ...config.params, t: new Date().getTime() }
}
//如果是post qs将json转成key/value
if (Object.values(config.headers).includes('application/x-www-form-urlencoded')) {
config.data = qs.stringify(config.data)
}
return config
},
error => {
return Promise.reject(error)
}
)
// 响应拦截器
$http.interceptors.response.use(
response => {
const res = response.data
return res
},
error => {
return Promise.reject(error)
}
)
// 导出 axios 实例
export default $http
main.js
import $http from './utils/request'
//globalProperties 全局 app的全局属性名为$axios
app.config.globalProperties.$axios = $http;
login(){
//后端解决跨域
var that = this; // 函数内的this指向函数 没有指向data
that.$axios.post("vuelogin", {
username: that.username,
password:that.password
})
.then(function (response) {
console.log(response)
//处理成功情况
// response.data.meta.status === 200
//1.const res = response.data return res响应拦截器 2. === 数据类型也要相同
if (response.meta.status === 200) {
//保持token到本地
let admin = response.data;
localStorage.setItem("token", admin.username);
//跳转页面
that.$router.push({
name: 'home',
query: {
username: admin.username
}
});
} else {
that.user = "";
that.password = "";
alert(response.meta.msg);
}
})
.catch(function (error) {
//处理错误情况
console.log(error);
alert("服务器出错..")
})
}
删除token
alert(response.meta.msg);
}
})
.catch(function (error) {
//处理错误情况
console.log(error);
alert("服务器出错..")
})
}
原因:验证码更新
使用session,创建session对象把JSessionId 以cookie的形式保存在客户端浏览器。 没有携带cookieID ,会再次使用session
axios默认不携带cookie
解决:在request.js或main.js中
//CROS跨域是否允许凭证
$http.defaults.withCredentials = true;
request.js 表单登录 key/value
headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' }
CrossFilter
HttpServletRequest request = (HttpServletRequest) req;
// response.setHeader("Access-Control-Allow-Origin", "*"); //允许所有的域名访问
//axios允许携带cookie Access-Control-Allow-Origin"不能设置为 "*"
//设置为携带cookie的前端域名"https://localhost"
//动态获取request.getHeader("origin")