如何使用 api 在服务器端呈现反应?
Posted
技术标签:
【中文标题】如何使用 api 在服务器端呈现反应?【英文标题】:How to render react on server-side with an api? 【发布时间】:2017-07-17 06:27:42 【问题描述】:为了清楚起见,我使用的是 MongoDB、Express、React 和 Node 堆栈。
我现在正在尝试学习 react.js。我掌握了正确的基础知识,并且能够使用路由器编写一个简单的反应应用程序。我还尝试过在服务器端渲染一个简单的反应应用程序,它也可以完美运行。但是,我现在有点卡住了,因为我想制作一个带有 rest api 和服务器端渲染的完整应用程序。
1) 我不知道应该如何在服务器文件中分离 api 和 react 代码。会从列出 api 调用开始,然后进行服务器端渲染工作吗? 像这样:
app.get('/api/whatever', function(req, res)
//get whatever
);
app.get('*', function(req, res)
//math routes and renderToString React
);
2)另外,我什至无法测试上述内容的原因是,当我尝试使用 nodemon 运行服务器时,它会抛出错误,因为它不理解反应代码,我应该怎么做呢?我应该以某种方式配置 nodemon 以读取 es6 还是忽略它或配置 webpack 以运行 express 服务器?
3) 最后一个问题可以很容易地弄清楚整个故事。我试图找到一个答案,但得到了许多相互矛盾的答案。谷歌爬虫是否能够爬取 React 应用程序?我正在学习 SEO 的服务器端渲染,真的有必要吗?
抱歉问题太长了,期待阅读您的回答。
【问题讨论】:
你在第二个 app.get 函数中给出了什么响应? app.get("*",function(req, res) ReactRouter.match(routes:AppRoutes, location:req.url, function(err, redirectLocation, renderProps) if ( err) res.send(500, err.message) else if (redirectLocation) res.redirect(302, redirectLocation.pathname + redirectLocation.search) else if (renderProps) res.send(200, ReactDOMServer.renderToString (我的做法与您在我目前正在处理的项目中的代码示例中的做法相同——我匹配 *,然后使用 React Router 呈现不同的页面。 I wrote a blog article about this, with code examples.
在我的设置中,我使用 webpack 来编译我的后端代码,就像我使用前端代码一样。我使用 watch 机制来监听代码的变化,并在重新编译后自动重启节点服务器。不需要nodemon。
#!/usr/bin/env node
const path = require('path');
const webpack = require('webpack');
const spawn = require('child_process').spawn;
const serverConfig = require('webpack.config.server');
const compiler = webpack(serverConfig);
const watchConfig =
aggregateTimeout: 300,
poll: 1000,
ignored: '**/*.scss'
;
let serverControl;
compiler.watch(watchConfig, (err, stats) =>
if (err)
console.error(err.stack || err);
if (err.details)
console.error(err.details);
return;
const info = stats.toJson();
if (stats.hasErrors())
info.errors.forEach(message => console.log(message));
return;
if (stats.hasWarnings())
info.warnings.forEach(message => console.log(message));
if (serverControl)
serverControl.kill();
serverControl = spawn('node', [path.resolve(__dirname, '../../dist/polly-server.js')]);
serverControl.stdout.on('data', data => console.log(`$new Date().toISOString() [LOG] $data`));
serverControl.stderr.on('data', data => console.error(`$new Date().toISOString() [ERROR] $data`));
);
-
是的,Google 会抓取客户端的 React 代码,但服务器端渲染仍然是个好主意,因为抓取结果可能会不一致,尤其是在 Ajax 调用后动态加载部分页面时
【讨论】:
感谢您的回答,这正是我所希望的。但是,在您博客文章的演示中,您从 git hub api 获取数据。有一个存在于 server.js 文件中的 api 会起作用吗? '*' 不会与 '/api' 冲突,因为它处理所有请求吗?我想我会尝试一下,看看会发生什么。 没有冲突,只要确保你的 * 匹配在最后,顺序很重要以上是关于如何使用 api 在服务器端呈现反应?的主要内容,如果未能解决你的问题,请参考以下文章
react + redux + saga +服务器端渲染+如何停止服务器端渲染页面的额外ajax调用?