正在为ReactAsync清除localhost:3000个URL

Getting rid of localhost:3000 URLs for ReactAsync

本文关键字:3000个 URL localhost 清除 ReactAsync      更新时间:2023-09-26

交叉过账到https://github.com/andreypopp/react-async/issues/34

当使用react async时,通常会有如下代码:

var UserPage = React.createClass({
  mixins: [ReactAsync.Mixin],
  statics: {
    getUserInfo: function(username, cb) {
      superagent.get(
        'localhost:3000/api/users/' + username,
        function(err, res) {
          cb(err, res ? res.body : null);
        });
    }
  },
  getInitialStateAsync: function(cb) {
    this.type.getUserInfo(this.props.username, cb);
  },
  ...

这个问题是它在服务器上运行的浏览器中正确运行。

使用使URL相对的明显解决方案(例如'/api/users/' + username有一个微妙的问题。

在页面之间移动时,它似乎起作用,但在页面重新加载或初始加载时不起作用。(在ReactJS应用程序中,你实际上并没有在页面之间移动,只是URL发生了变化。)

这个问题的原因是,在服务器端渲染期间,服务器需要调用AJAX API,但服务器不知道浏览器看到的页面来源(http://www.example.com:3000)。

有没有一种方法可以告诉服务器端渲染器这一点?

(我已经想到了一种糟糕的解决方案,即客户端和服务器都使用完整的URL,但必须为运行代码的每个开发、测试和生产服务器明确配置。)

首先,为超级代理使用一个简单的插件函数。这将重写绝对url,但仅在服务器上进行。这意味着浏览器将向"/api"发出请求,服务器将向"localhost:port/api"发送请求。

function fixUrlPlugin(port){
  return function fixUrl(req){
    if (process.browser) return req;
    if (req.url[0] === '/') {
        req.url = 'localhost:' + port + req.url
    }
    return req;
  };
}

现在,在代码的某个地方,您将运行此程序并将输出保存在模块中。

app.listen(8080);
module.exports = fixUrlPlugin(8080);

然后你的代码就可以来了:

var urlPlugin = require('./path/to/that/module.js');
// ...
  statics: {
    getUserInfo: function(username, cb) {
      superagent.get('/api/users/' + username)
        .use(urlPlugin)
        .end(function(err, res) {
          cb(err, res ? res.body : null);
        });
    }
  },