react+spring 记录跨域问题的解决方法

发布日期:2019-05-10

react 跨域访问后台,默认是有跨域问题,并且火弧和谷歌浏览器,对跨域问题展示还不一样.

谷歌浏览器如下图:

此处状态是200,然而在Response却没有任何信息,如下图

 

然而火弧浏览器,对该问题的描述,就清淅得多,

火弧浏览器告诉我们,跨域了,关于react跨域的帖子,网上也有相关帖子,搜索到的方法,大约都是如下解决方式:

如果你是通过creat-react-app构建的项目,请在package.json文件中的根目录下,添加"proxy": "http://api.xxxx.com",如果你的项目,需要调用多个不同ip的接口,请使用如下配置:

"proxy": { "/api/RoomApi": { "target": "http://open.douyucdn.cn" "changeOrigin":true } "/api/v1":{ "target":"http://capi.douyucdn.cn" "changeOrigin":true } }

对于antd-pro的项目,需要在package.json的同等目录下添加.roadhogrc文件,具体代码如下:

{ "entry": "src/index.js" "extraBabelPlugins": [ "transform-runtime" "transform-decorators-legacy" "transform-class-properties" ["import" { "libraryName": "antd" "libraryDirectory": "es" "style": true }] ] "env": { "development": { "extraBabelPlugins": [ "dva-hmr" ] } } "externals": { "g2": "G2" "g-cloud": "Cloud" "g2-plugin-slider": "G2.Plugin.slider" } "ignoreMomentLocale": true "theme": "./src/theme.js" "proxy": { "/api": { "target": "http://api.xxxx.com/" "changeOrigin": true } } }

配置完成后,再次访问接口,还是出现一样的跨域问题,既然recat的配置,未解决跨域问题,我就把思路转到spring,在spring去处理跨域,在后端程序添加一个拦截器

package com.gg.interceptorimport java.util.ArrayListimport java.util.Listimport java.util.Vectorimport javax.servlet.http.HttpServletRequestimport javax.servlet.http.HttpServletResponseimport org.springframework.web.servlet.HandlerInterceptorimport org.springframework.web.servlet.ModelAndViewpublic class ProcessInterceptor implements HandlerInterceptor{ @Override public boolean preHandle(HttpServletRequest httpServletRequest HttpServletResponse httpServletResponse Object handler) throws Exception { // TODO Auto-generated method stub // 指定白名单域名 http://localhost:8000http://localhost:8000 List<String> whileList = new Vector<String>() whileList.add("http://127.0.0.1:8000") whileList.add("http://localhost:8000") String clientIp = httpServletRequest.getHeader("origin") boolean status = false for(String ip : whileList) { if(clientIp!=null&&clientIp.equals(ip)) { status = true break } } /** * 网上解决方案是httpServletResponse.setHeader("Access-Control-Allow-Origin""*")设置后发现,还是不能处理跨域问题,需要指定某一个ip,如:http://127.0.0.1:8000 * */ httpServletResponse.setHeader("Access-Control-Allow-Origin"status?clientIp:null) //响应头设置 httpServletResponse.setHeader("Access-Control-Allow-Headers" "Content-TypeContent-Length Authorization AcceptX-Requested-With") //响应类型 httpServletResponse.setHeader("Access-Control-Allow-Methods""PUTPOSTGETDELETEOPTIONS") httpServletResponse.setHeader("X-Powered-By""Jetty") httpServletResponse.setHeader("Access-Control-Allow-Credentials""true") String method= httpServletRequest.getMethod() if (method.equals("OPTIONS")){ httpServletResponse.setStatus(200) return false } System.out.println(method+"status:"+status+"clientIp:"+clientIp) return true } @Override public void postHandle(HttpServletRequest request HttpServletResponse response Object handler ModelAndView modelAndView) throws Exception { // TODO Auto-generated method stub } @Override public void afterCompletion(HttpServletRequest request HttpServletResponse response Object handler Exception ex) throws Exception { // TODO Auto-generated method stub }}

spring-servlet.xml配置如下:

<mvc:interceptors> <bean class="com.gg.interceptor.ProcessInterceptor"></bean> </mvc:interceptors>

react客户端代码如下:

Model层js代码:*login({ payload } { call put }){ let formData = new FormData() formData.append("loginId"payload.loginId)//账号 formData.append("passWord"payload.passWord)//密码 const response = yield call(requestGuangGao formData) yield put({ type: "changeLoginStatus" payload: response }) }api层js代码:export async function requestGuangGao(formData){ // let formData = new FormData() // formData.append("loginId"params.loginId) // formData.append("passWord"params.passWord) console.log("requestGua >url :" ) return request("http://127.0.0.1:8080/guanggao/userController/login.do" { method: "POST" mode: "cors" body:formData }) }

通过以下设置,react跨域问题就处理好了。