摆脱localhost:ReactAsync的3000个URL

时间:2014-10-20 10:55:41

标签: javascript reactjs react-async

交叉发布到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,但必须为运行代码的每个开发,测试和生产服务器明确配置。)

1 个答案:

答案 0 :(得分:3)

首先,为superagent使用一个简单的插件函数。这会重写绝对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);
        });
    }
  },