如何使用 axios 通过 webpack 开发服务器向远程服务器上的 API 发送请求

IT技术 reactjs webpack proxy remote-access remote-server
2022-07-24 01:37:19

我想从支持 REST API 的远程服务器获取一些数据。我正在使用 axios 和 web-dev-server。我的前端正在发送请求,我同时使用了 firefox 和 chrome 打开我的前端。但是,每次我尝试提出请求时,都会遇到 cors 错误。此外,我不想在我的服务器上进行任何更改。Firefox 和 chrome 正在发送此标头。

接受:*/*
接受编码:gzip,放气
接受语言:en-US,en;q=0.5
连接:保持活动
主机:my.ip.to.host:port
来源:http://localhost:3000
引用者:http://localhost:3000/login
用户代理:Mozilla/5.0 (X11; Ubuntu; Linu…) Gecko/20100101 Firefox/67.0

我试图在没有 web-dev-server 的在线平台上运行我的简单请求代码,并且运行得非常好。

这是我的代码

      //********** 我的请求*********
    返回 axios
        .get(' http://my.ip.to.host:port/api/User/login ', {
            标题:{
                接受:' / '
            }
        })
        .then(函数(响应){
            控制台日志(响应);
            返回“用户”;
        })
        .catch(函数(错误){
            控制台日志(错误);
            返回“错误”;
        });
     //**********************************
    
     //*****webpack.config.js********
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    需要('babel-polyfill');
    module.exports = {
        模式:'发展',
        条目:['babel-polyfill','./src'],
        解决: {
            扩展名:['.js', '.jsx']
        },
        module: {
            规则:[
                {
                    测试:/.jsx?$/,
                    加载器:'babel-loader'
                }
            ]
        },
        插件:[
            新的 HtmlWebpackPlugin({
                模板:'./src/index.html'
            })
        ],
        开发服务器:{
            historyApiFallback: true,
            端口:3000
        },
        外部:{
            // 全局应用配置对象
            配置:JSON.stringify({
                apiUrl: ' http://localhost:4000 ',
                checkLogin: ' http://my.ip.to.host:port/api/User/login '
            })
        }
    };
    

这是我得到的错误。

跨域请求被阻止:同源策略不允许在 http://my.ip.to.host:port/api/User/login 读取远程资源。(原因:缺少 CORS 标头“Access-Control-Allow-Origin”)。`在此处输入代码`
2个回答

您需要在 axios 配置中withCredentials进行设置。Cors 设置true

let HttpInterceptor = axios.create({
  headers: {
    Accept: "*/*"
  }
});

HttpInterceptor.interceptors.request.use(
  function(config) {  
    config.withCredentials = true; // To enable CORS
    return config;
  },
  function(error) {
    return promise.reject(error);
  }
);



//********** Your request*********
    return HttpInterceptor
        .get('http://my.ip.to.host:port/api/User/login')
        .then(function(response) {
            console.log(response);
            return 'user';
        })
        .catch(function(error) {
            console.log(error);
            return 'err';
        });

Google 在这里很好地解释了 cors(跨域请求)。

我通过托管代理服务器(在我托管客户端的同一本地服务器上)并通过它重定向我的所有单页应用程序请求来解决此问题。

首先,我在 webpack 配置文件的 devsever 键中创建了一个代理设置,如下所示。



    devServer: {
        proxy: {
    //abc is REST API request endpoint on my backend
            '/abc': {
                //target is where your proxy server is hosted
                target: 'http://localhost:5000',
                secure: 'false'
            },
    //xyz is REST API request endpoint on my backend
            '/xyz': {
                //target is where your proxy server is hosted
                target: 'http://localhost:5000',
                secure: 'false'
            }
        },......// rest of the setting
      }

然后,对于通过我的客户端对某个操作的特定调用,我会像这样向我的后端发出请求。



    axios
        .get('/startAppkey', { withCredentials: true })// withCredential enables passing of cookies and session id. If you dont want to creat session you can avoid this.
        .then((response) => {
                           // do stuff with response
                            })
                        .catch(function() {
                         //do stuff
                        });

我们的客户已准备就绪。现在是代理服务器的时候了。首先安装http-proxy-middleware,像这样。



    sudo npm i --save http-proxy-middleware
    //it is also avilable on yarn

然后,在这里设置代理服务器只需几行代码。


    从'express'导入*作为快递;// 使用 express 来支持我的中间件
    从 'http-proxy-middleware' 导入 * 作为代理;
    常量应用程序 = 快递();
    // 路径 /abc 和 /xyz 应该和你在 webpack 配置文件中声明的一样
    app.use('/abc', proxy({ target: 'http://your/backend/api/endpoint'}));
    app.use('/xyz', proxy({ target: 'http://your/backend/api/endpoint'}));
    //就是这样,你在这里完成了。