解决 vue axios 带 header 时,会默认发起 OPTIONS 请求的方法的问题

This commit is contained in:
YunaiV 2019-03-27 19:12:12 +08:00
parent 42b11e377e
commit c23eb737f0
10 changed files with 182 additions and 17 deletions

View File

@ -39,4 +39,4 @@ function getLocalStorage(key) {
} catch (e) { } catch (e) {
throw new Error(`localStorage 获取错误! ${e}`); throw new Error(`localStorage 获取错误! ${e}`);
} }
} }

View File

@ -0,0 +1,35 @@
package cn.iocoder.common.framework.servlet;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class CorsFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) { }
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletResponse resp = (HttpServletResponse) response;
resp.setHeader("Access-Control-Allow-Origin", "*");
resp.setHeader("Access-Control-Allow-Methods", "*");
resp.setHeader("Access-Control-Allow-Headers", "*");
resp.setHeader("Access-Control-Max-Age", "1800");
// For HTTP OPTIONS verb/method reply with ACCEPTED status code -- per CORS handshake
// 例如说vue axios 请求时会自带该逻辑的
HttpServletRequest req = (HttpServletRequest) request;
if (req.getMethod().equals("OPTIONS")) {
resp.setStatus(HttpServletResponse.SC_ACCEPTED);
return;
}
// 如果是其它请求方法则继续过滤器
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
}

View File

@ -71,5 +71,33 @@ export function ExchangeCoupon(code){
}) })
} }
export function getUserInfo() {
return request({
url: 'user-api/users/user/info',
method: 'get',
headers: {
test: 1,
}
});
}
export function doPassportMobileRegister(mobile, code) {
return request({
url: 'user-api/users/passport/mobile/register',
method: 'post',
params: {
mobile,
code,
}
});
}
export function doPassportMobileSendRegisterCode(mobile) {
return request({
url: 'user-api/users/passport/mobile/send_register_code',
method: 'post',
params: {
mobile,
}
});
}

View File

@ -18,6 +18,10 @@ if (process.env.NODE_ENV == 'development') {
baseUrl = ''; baseUrl = '';
} }
baseUrl = 'http://127.0.0.1';
dataSources = 'remote';
// dataSources = 'local';
export { export {
baseUrl, baseUrl,
routerMode, routerMode,

View File

@ -1,11 +1,14 @@
import axios from 'axios' import axios from 'axios'
import {baseUrl, dataSources} from './env'; import {baseUrl, dataSources} from './env';
import datas from '../data/data'; import datas from '../data/data';
import { getAccessToken } from '../utils/cache.js';
const service = axios.create({ const service = axios.create({
baseURL: baseUrl, // api 的 base_url baseURL: baseUrl, // api 的 base_url
timeout: 5000, // request timeout timeout: 5000, // request timeout
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
}); });
const servicef = function (parameter) { const servicef = function (parameter) {
@ -21,6 +24,15 @@ const servicef = function (parameter) {
}) })
return promist; return promist;
} }
// 设置 access token
// debugger;
// if (getAccessToken()) {
// parameter.headers = {
// ...parameter.headers,
// 'Authorization': `Bearer ${getAccessToken()}`,
// };
// }
// debugger;
return service(parameter); return service(parameter);
} }
@ -33,6 +45,11 @@ service.interceptors.request.use(
// config.headers['X-Token'] = getToken() // config.headers['X-Token'] = getToken()
// } // }
debugger;
if (getAccessToken()) {
config.headers['Authorization'] = `Bearer ${getAccessToken()}`;
}
return config return config
}, },
error => { error => {

View File

@ -82,21 +82,32 @@
</template> </template>
<script> <script>
import { GetUserIndex } from "../../api/user.js"; // import { GetUserIndex } from "../../api/user.js";
import { getAccessToken } from '../../utils/cache.js';
import { getUserInfo } from '../../api/user.js';
export default { export default {
data(){ data(){
return{ return{
data:{} data: {},
user: {},
} }
}, },
components: { components: {
}, },
created:function(){ created:function(){
GetUserIndex().then(response=>{ // GetUserIndex().then(response=>{
this.data=response; // this.data=response;
}); // });
}, },
mounted() {
if (getAccessToken()) { //
let response = getUserInfo();
response.then(data => {
this.user = data;
});
}
}
}; };
</script> </script>

View File

@ -3,10 +3,10 @@
<headerNav title="账号管理"/> <headerNav title="账号管理"/>
<van-cell-group> <van-cell-group>
<van-cell title="修改个人信息" is-link /> <van-cell title="修改个人信息" is-link />
<van-cell title="修改登录密码" is-link /> <!--<van-cell title="修改登录密码" is-link />-->
<van-cell title="修改绑定手机" is-link /> <!--<van-cell title="修改绑定手机" is-link />-->
<van-cell title="关联账号" is-link /> <!--<van-cell title="关联账号" is-link />-->
<van-cell title="切换账号" is-link to="/login" /> <!--<van-cell title="切换账号" is-link to="/login" />-->
</van-cell-group> </van-cell-group>
</div> </div>
</template> </template>
@ -19,4 +19,4 @@ export default {
<style> <style>
</style> </style>

View File

@ -0,0 +1,46 @@
/* eslint-disable */
// localStorage 操作
const cacheKeys = {
accessTokenKey: 'accessToken',
refreshTokenKey: 'refreshToken',
};
///
/// 设置 loginToken分为 accessToken 和 refreshToken
export function setLoginToken(accessToken, refreshToken) {
setLocalStorage(cacheKeys.accessTokenKey, accessToken);
setLocalStorage(cacheKeys.refreshTokenKey, refreshToken);
}
export function getLoginToken() {
const res = {};
res[cacheKeys.accessTokenKey] = getLocalStorage(cacheKeys.accessTokenKey);
res[cacheKeys.refreshTokenKey] = getLocalStorage(cacheKeys.refreshTokenKey);
return res;
}
export function getAccessToken() {
return getLocalStorage(cacheKeys.accessTokenKey);
}
///
/// 设置 localStorage 公共方法
function setLocalStorage(key, value) {
try {
localStorage.setItem(key, value);
} catch (e) {
throw new Error(`localStorage 设置错误! ${e}`);
}
}
function getLocalStorage(key) {
try {
return localStorage.getItem(key);
} catch (e) {
throw new Error(`localStorage 获取错误! ${e}`);
}
}

View File

@ -1,16 +1,16 @@
package cn.iocoder.mall.user.application.config; package cn.iocoder.mall.user.application.config;
import cn.iocoder.common.framework.config.GlobalExceptionHandler; import cn.iocoder.common.framework.config.GlobalExceptionHandler;
import cn.iocoder.common.framework.servlet.CorsFilter;
import cn.iocoder.mall.admin.sdk.interceptor.AdminSecurityInterceptor; import cn.iocoder.mall.admin.sdk.interceptor.AdminSecurityInterceptor;
import cn.iocoder.mall.user.sdk.interceptor.UserAccessLogInterceptor; import cn.iocoder.mall.user.sdk.interceptor.UserAccessLogInterceptor;
import cn.iocoder.mall.user.sdk.interceptor.UserSecurityInterceptor; import cn.iocoder.mall.user.sdk.interceptor.UserSecurityInterceptor;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@EnableWebMvc @EnableWebMvc
@Configuration @Configuration
@ -27,6 +27,7 @@ public class MVCConfiguration implements WebMvcConfigurer {
@Override @Override
public void addInterceptors(InterceptorRegistry registry) { public void addInterceptors(InterceptorRegistry registry) {
// CORS
// 用户 // 用户
registry.addInterceptor(userAccessLogInterceptor).addPathPatterns("/users/**"); registry.addInterceptor(userAccessLogInterceptor).addPathPatterns("/users/**");
registry.addInterceptor(userSecurityInterceptor).addPathPatterns("/users/**"); // 只拦截我们定义的接口 registry.addInterceptor(userSecurityInterceptor).addPathPatterns("/users/**"); // 只拦截我们定义的接口
@ -41,4 +42,21 @@ public class MVCConfiguration implements WebMvcConfigurer {
registry.addResourceHandler("webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); registry.addResourceHandler("webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
} }
// TODO 芋艿允许跨域
// @Override
// public void addCorsMappings(CorsRegistry registry) {
// registry.addMapping("/**")
// .allowedHeaders("*")
// .allowedMethods("*")
// .allowedOrigins("*");
// }
@Bean
public FilterRegistrationBean<CorsFilter> corsFilter() {
FilterRegistrationBean<CorsFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new CorsFilter());
registrationBean.addUrlPatterns("/*");
return registrationBean;
}
} }

View File

@ -8,6 +8,7 @@ import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
@ -37,6 +38,11 @@ public class UserAccessLogInterceptor extends HandlerInterceptorAdapter {
@Override @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
// TODO 芋艿临时拿来处理 vue axios options 请求的问题
if (HttpMethod.OPTIONS.matches(request.getMethod())) {
return false; // 通过这样的方式让前端知道允许的 header 等等
}
// 记录当前时间 // 记录当前时间
START_TIME.set(new Date()); START_TIME.set(new Date());
return true; return true;