如何在React / Webpack中创建代理以调用外部API

时间:2017-09-24 19:08:41

标签: reactjs webpack proxy create-react-app

我想向我无法控制的外部API发出GET请求。由于API的安全性,我的react应用程序无法直接向端点发出ajax请求。因此,我尝试创建一个简单的代理,如演示here

我的package.json file看起来像这样:

{
  "name": "my-stack",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "react": "^15.6.1",
    "react-dom": "^15.6.1",
    "react-router-dom": "^4.2.2",
    "react-scripts": "1.0.13"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "proxy": {
    "https://gold-feed.com/paid/*": {
        "target": "https://gold-feed.com/paid",
        "changeOrigin": true
    }
  }
}

然后我的ajax请求看起来像这样:

const apiUrl = 'https://gold-feed.com/paid/<apiID>/all_metals_json_usd.php';

jQuery.ajax({
  method: 'GET',
  url: apiUrl,
  success: (item) => {
    this.props.addItem(item);
  }
});

但它似乎没有做任何事情。我仍然收到以下错误:

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.

我基本上遇到了与记录here相同的问题,他正在尝试创建一个代理来访问Steam api。

只是旁注,我相信我正在使用的create-react-app项目正在抄袭webpack。

3 个答案:

答案 0 :(得分:5)

你可能现在已经知道了,但对于其他人来说这是有效的 我:

"proxy": {
    "/proxy": {
        "target": "https://mybackend.com",
        "pathRewrite": {
                "^/proxy" : ""
        },
        "changeOrigin": true
    }
}

因此myreact.com/proxy/my/path被重定向到mybackend.com/my/path

我认为您的错误是您将目标作为代理的密钥而不是反应服务器上的路径。

答案 1 :(得分:0)

对于我来说,我的api已部署在AWS上,我发现该设置

"changeOrigin": true

是必要的(chrome和edge正常,firefox(62.0.3)抱怨“无效的CORS请求”。)

在webpack http代理的文档中,他们说此选项: (https://github.com/chimurai/http-proxy-middleware

  

提示:对于基于名称的虚拟托管站点,将选项changeOrigin设置为true。

注释:

  • 在同一台计算机上本地运行api并不需要它。
  • firefox添加了标头“ origin”,当我删除并重新发送请求后,该标头就起作用了。
  • 添加“ changeOrigin”没有副作用,因此我将从现在开始这样做。

我不确定这是不是Firefox中的错误还是什么,总之我的最终配置是:

"proxy": {
  "/api": {
    "target": "<put ip address>",
    "changeOrigin" : true
  }
}

您应将/ api替换为api的路径,或将路径重写为上面的答案。

答案 2 :(得分:0)

您可以将外部API代理到localhost,更改前端来源(localhost:3000),目标服务器,必要时更新令牌,并在节点js中运行以下脚本

const express = require('express');
const proxy = require('express-http-proxy');
const cors = require("cors");

const app = express();

app.use(
  cors({
    origin: 'localhost:3000',
    credentials: false
  })
);

app.use('/', proxy('https://www.targetserver.com/', {
  proxyReqPathResolver: function (req) {
    return req.url;
  },
  proxyReqOptDecorator: function (proxyReqOpts, srcReq) {
    proxyReqOpts.headers = {'Authorization': 'Replace with JWT'};
    return proxyReqOpts;
  }
}))

app.get('/*',function(req,res,next){
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});


app.listen(4000, () => console.log(`Server Listening on port ${4000}!`));

像这样(在axios或fetch中)在fontend应用程序中使用它:

axios.get('http://localhost:4000/api/route).then(x => console.log(x));