【问题标题】:Problem with Proxy built to handle CORS issue为处理 CORS 问题而构建的代理问题
【发布时间】:2020-03-18 08:44:13
【问题描述】:

http://localhost:3002(源)和http://localhost:8080/configurator(服务器)之间进行本地测试时遇到CORS问题

所以我决定在它们之间建立一个代理,它将 access-control-allow origins 标头附加到服务器的任何响应中。我似乎得到了一个好的回应,但并没有给我身体本身。忽略客户端代码,我只是想用邮递员(客户端软件)-> 代理(节点快递)和终端服务器(球衣)进行测试

我在邮递员中的请求发送到http://localhost:3001/file/(代理)并发送一个 JSON 字符串内容类型标头设置为 application/json 代理代码如下

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
const request = require('request');
var logger = require('morgan');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  next();
});

app.post('/file', (req, res) => {
  request.post(
    { url: 'http://localhost:8080/configurator' },
    (error, response, body) => {
      if (error || response.statusCode !== 200) {
        return res.status(500).json({ type: 'error', message: err.message });
      }

      //console.log("body is"+body)
      //return res.json(body)//res.send(body)
       return res.send(body)
      //return res.send(JSON.parse(body));
      //return res.json(JSON.parse(body));
    }
  )
});

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

const PORT = 3001;
app.listen(PORT, () => console.log(`listening on ${PORT}`));

module.exports = app;

代理将请求转发到我的后端并将 CORS 标头附加到响应中。

下一个我添加的后端端点是 POST,它只是获取一个 JSON 字符串然后尝试返回它。

package ie.sidero.resources;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

@Path("/configurator")
public class ConfiguratorFileResource {

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public String getJsonConfigurationFile(){
        return "File/JSON will get returned here";
    }

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.TEXT_PLAIN)
    public String addJsonConfigurationFile(String jsonConfiguration){
        return jsonConfiguration;
        //return Response.ok("Got the JSON it is: " + jsonConfiguration).header("Access-Control-Allow-Origin", "*").build();
        //return Response.status(Response.Status.OK).entity(jsonConfiguration).build();
    }
}

我的问题是我只返回一个空字符串。我附上了两张图片,一张在代理中显示控制台输出,说正文为空,在邮递员中显示类似的结果。我在这里做错了什么?

更新:所以我的代理现在可以使用以下代码:

app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  req.header('Content-Type', 'application/json');
  next();
});

app.post('/file', (req, res) => {
  request.post(
    { url: 'http://localhost:8080/configurator',
      body: JSON.stringify(req.body)},
    (error, response, body) => {
      if (error || response.statusCode !== 200) {
        return res.status(500).json({ type: 'error', message: err.message });
      }

       //var r = JSON.parse(body);
       //console.log("response body after send is: " +r)

       return res.json(JSON.parse(body));

    }
  )
});

至少看起来是这样。现在,当我使用邮递员时,向 localhost:8080/configurator(后端)或 localhost:3001/file(代理)发送请求会返回相同的结果,但是当我使用客户端应用程序并进行 ajax 调用时,我仍然在输出中看到 CORS 问题,可能现在的问题是,我什至用下面附加的ajax调用来调用我的代理,任何帮助都会很棒。有什么问题就问吧。

$.ajax({
            url: "http://localhost:3001/file", // Url to which the request is send
            type: "POST",             // Type of request to be send, called as method
            data: configJsonEdited,
            contentType: 'application/json',
            dataType: "json",         //Data expected back
            success: function(data)   // A function to be called if request succeeds
            {
                alert("YAY!!!!")
            },
            error: function(xhr, textStatus, errorThrown)
            {
                alert("Damnit!!")
                alert(textStatus);
                alert(errorThrown.toString());
            }
        });

【问题讨论】:

  • 只是还想添加直接与邮递员请求后端本身而不通过代理工作正常,但如果我使用我的客户端应用程序由于cors问题而无法工作所以我觉得有问题代理部分
  • 是否需要通过请求体?即使没有收到请求正文,您的后端是否也会返回 200?我真的认为您应该使用现有的代理,而不是尝试使用自己的代理。已经有 NodeJS HTTP 代理,或者你可以使用 nginx 和类似的。对于一个小而简单的有限案例,编写自己的代码很容易,但是这样做有很多错误,它应该返回 502 而不是 500,大多数错误都传递给客户端,它不处理身份验证,标头丢失等等等。为什么要让自己承受这种痛苦?一个好的股票代理会起作用
  • 嗨,迈克尔,我必须添加很多验证,这不是我要问的。目前我只是想获得最基本的功能。我发现代理从未发送过 JSON,因为它没有被传递我更新了代码和控制台日志显示我现在得到了 json 数据但不确定我是否正确发送它``` request.post( { url: 'localhost:8080/configurator', data: JSON.stringify(req.body)}, ``` 当控制台记录 req.body 时我可以看到 json
  • 是的,我认为您发布的内容很可疑,但没有通过请求正文发送,但显然您的后端仍然必须返回 200 ......我仍然认为您不应该滚动自己的代理,如果 http-proxy (npm) 无法完成您关心的所有验证,而不会给您带来 1000 个潜在的小问题(例如忘记通过请求正文)的负担,我会感到惊讶。
  • 如何转发通过request.post方法收到的json?

标签: jquery node.js reactjs cors jersey


【解决方案1】:

通过将此依赖项添加到我的代理解决了 CORS 问题:

https://expressjs.com/en/resources/middleware/cors.html

【讨论】:

    【解决方案2】:

    最好不要从头开始编写代理。如果你真的想要一个 nodejs 代理,你可以使用 http-proxy 这样的东西:

    const http = require('http');
    const httpProxy = require('http-proxy');
    
    const proxy = httpProxy.createProxyServer();
    
    const server = http.createServer(function(req, res) {
        proxy.web(req, res, { target: 'http://localhost:8080' });
    });
    
    proxy.on('proxyRes', function (proxyRes, req, res) {
        res.setHeader('foo', 'bar');
    }).on('error', function (e) {
        console.error(e);
    });
    
    server.listen(3001);
    

    这只是一个愚蠢的例子,我从the http-proxy docs 粘贴了一些代码,错误处理显然不足以用于生产目的,但它表明您可以轻松创建代理并修补响应(在这种情况下,我添加了一个标题,因为这是您的主要用例)。

    我刚刚对我的服务器进行了尝试,它传入了请求正文,然后进行了身份验证,它传回了错误和成功的 http 响应,并始终添加 foo 标头。

    【讨论】:

    • 嗨迈克尔,所以这两种方法都可以工作,我设法让我的代理也通过邮递员的测试工作,但是当我尝试来自我的相同 ajax 请求时,我仍然看到 COR 的问题和 404 未找到问题应用
    猜你喜欢
    • 2019-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-11
    • 2020-01-12
    • 1970-01-01
    • 2015-06-17
    • 1970-01-01
    相关资源
    最近更新 更多