欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-04-28 21:35:47
react 跨域访问后台,默认是有跨域问题,并且火弧和谷歌浏览器,对跨域问题展示还不一样. 谷歌浏览器如下图: 此处状态是200,然而在Response却没有任何信息,如下图 然而火弧浏览器,对该问题的描述,就清淅得多, 火弧浏览器告诉我们,跨域了,关于react跨域的帖子,网上也有相关帖子,搜索到 ......

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

谷歌浏览器如下图:

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

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

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

 

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

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

火弧浏览器告诉我们,跨域了,关于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.interceptor;

import java.util.arraylist;
import java.util.list;
import java.util.vector;

import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;

import org.springframework.web.servlet.handlerinterceptor;
import org.springframework.web.servlet.modelandview;

public class processinterceptor implements handlerinterceptor{

    @override
    public boolean prehandle(httpservletrequest httpservletrequest, httpservletresponse httpservletresponse, object handler)
            throws exception {
        // todo auto-generated method stub 
        // 指定白名单域名   http://localhost:8000,http://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-type,content-length, authorization, accept,x-requested-with");  
        //响应类型
        httpservletresponse.setheader("access-control-allow-methods","put,post,get,delete,options");  
        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跨域问题就处理好了。