我正在尝试使用服务器端渲染运行react应用程序。
我遇到的问题是,在浏览器上启用JS后,应用程序会加载,而根本不会访问服务器。
如果我关闭JS,应用程序将在服务器上正常加载。
下面是服务器上的app.js.为了100%透明,我开始使用各种示例,教程等开始我的SSR之旅。我已经删除了我认为不需要的所有内容,并且有一个可以理解的服务器处理渲染,但是如果我正在做的事情没有意义请告诉我:))
当事情发生时,我会在终端上显示一些简单的console.log()
语句。如上所述,如果在浏览器上关闭JS,我会看到这些消息并在终端中注销。如果JS开启,他们永远不会开火。
我认为我遗漏了一些非常明显的事情。
require('ignore-styles')
const bodyParser = require('body-parser')
const compression = require('compression')
const express = require('express')
const morgan = require('morgan')
const path = require('path')
const fs = require('fs')
const React = require('react')
const { Provider } = require('react-redux')
const { renderToString } = require('react-dom/server')
const { StaticRouter } = require('react-router-dom')
const { default: configureStore } = require('../src/store')
const { default: App } = require('../src/components/App')
require('babel-register')({
ignore: /\/(build|node_modules)\//,
presets: ['env', 'react-app']
})
// Routes
const index = require('./routes/index')
const universalLoader = require('./universal')
const app = express()
// Support Gzip
app.use(compression())
// Support post requests with body data (doesn't support multipart, use multer)
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: false }))
// Setup logger (only errors)
app.use(morgan('combined', {
skip: function (req, res) { return res.statusCode < 400 }
}))
app.use('/', index)
// Serve static assets
app.use(express.static(path.resolve(__dirname, '..', 'build')))
// Always return the main index.html, so react-router render the route in the client
app.use('/', function(req, res) {
console.log("ON SERVER")
const context = {}
const store = configureStore()
const filePath = path.resolve(__dirname, '..', 'build', 'index.html')
fs.readFile(filePath, 'utf8', (err, htmlData) => {
if(err){
console.error('read err', err)
return res.status(404).end()
}
// console.log("PreloadedState:", preloadedState)
const markup = renderToString(
<Provider store={store}>
<StaticRouter location={req.url} context={context}>
<App />
</StaticRouter>
</Provider>
)
// Somewhere a `<Redirect>` was rendered
if(context.url){
redirect(301, context.url)
// we're good, send the response
}else{
// Inject state and markup
const RenderedApp = htmlData.replace('{{SSR}}', markup)
console.log("SSR Render")
res.send(RenderedApp)
}
})
})
module.exports = app
修改
事实证明,客户端的服务工作者正在缓存页面本身,而服务器实际上并未受到攻击。因此,如果启用了JS,页面永远不会呈现服务器端。
我使用create-react-app
启动了应用:https://github.com/facebookincubator/create-react-app
此样板文件的默认设置是注册服务工作者。我不知道如何在允许服务工作者缓存资产等的同时禁用索引页面本身的缓存。
任何人都可以加入?