浏览器无法识别使用节点文件系统编写的 html 个文件
Browser doesn't recognize html files written with node file system
我正在使用 React 和 Apollo 2 构建一个应用程序,我正在尝试编写一个脚本来生成用于服务器端渲染的静态 html 文件。
我目前正在使用此逻辑在服务器上呈现我的 React 组件并且它工作正常:
export default (Page) => (req, res) => {
const App = (
<ApolloProvider client={client(fetch)}>
<Main>
<Page />
</Main>
</ApolloProvider>
);
getDataFromTree(App).then(() => {
const data = {
html: ReactDOMServer.renderToString(App),
seo: { title: "Home", description: "" }
};
res.render("index", { data });
});
}
但我想生成 .html
文件,这样我就可以静态地为它们提供服务,而无需每次都使用 运行 这种方法。我尝试将 renderToString
的结果编译为 .ejs
文件,然后使用 fs
写入文件,但没有成功。这是代码:
const component = ReactDOMServer.renderToString(App);
const template = ejs.compile(fs.readFileSync(path.join(__dirname, 'landing_template.ejs'), 'utf-8'));
const html = template({ component });
fs.writeFile(
path.join(__dirname, "../views/landing.ejs"),
html,
err => {
if(err) console.log(err);
else console.log("done.");
});
文件写入成功,但如果我打开我的页面源代码,编译方法添加的部分是灰色的,似乎被忽略了:
我也试过只读取文件并使用 .replace
替换字符串并插入一个虚拟 div
,但结果始终相同。
// using compile
const template = ejs.compile(fs.readFileSync(path.join(__dirname, 'landing_template.ejs'), 'utf-8'));
const html = template({ component });
const template = ejs.compile(fs.readFileSync(path.join(__dirname, 'landing_template.ejs'), 'utf-8'));
const html = template({ component: "<div>teste</div>" });
// using readFile
const template = fs.readFileSync(path.join(__dirname, 'landing_template.ejs'), 'utf-8');
const html = template.replace("<%- component %>", component);
const template = fs.readFileSync(path.join(__dirname, 'landing_template.ejs'), 'utf-8');
const html = template.replace("<%- component %>", "<div>teste</div>");
// maybe this is the problem?
fs.writeFile(
path.join(__dirname, "../views/landing.ejs"),
html,
{ encoding: "utf8" },
err => {
if(err) console.log(err);
else console.log("done.");
});
我猜浏览器无法将此新文本识别为 HTML 并且无法解析它。有谁知道我可以做这个的方法吗?
谢谢!
多么酷的主意!这可能是因为,正如您提到的,浏览器没有识别出您正在发送 html 这一事实。在调用 render:
之前尝试将 Content-Type
header 显式设置为 text/html
export default (Page) => (req, res) => {
const App = (
<ApolloProvider client={client(fetch)}>
<Main>
<Page />
</Main>
</ApolloProvider>
);
getDataFromTree(App).then(() => {
const data = {
html: ReactDOMServer.renderToString(App),
seo: { title: "Home", description: "" }
};
res.setHeader("Content-Type", "text/html");
res.render("index", { data });
});
}
编辑:
啊,我看到了!不幸的是,您不能在 HTML 中使用 self-close <script>
标签,这会使浏览器出错。像这样关闭 header 中的脚本标签:
<script async src="/build/app.bundle.js" type="text/javascript"></script>
这应该可以解决问题。
<script />
是错误的。你必须使用这个:
<script src="URL"></script>
我正在使用 React 和 Apollo 2 构建一个应用程序,我正在尝试编写一个脚本来生成用于服务器端渲染的静态 html 文件。
我目前正在使用此逻辑在服务器上呈现我的 React 组件并且它工作正常:
export default (Page) => (req, res) => {
const App = (
<ApolloProvider client={client(fetch)}>
<Main>
<Page />
</Main>
</ApolloProvider>
);
getDataFromTree(App).then(() => {
const data = {
html: ReactDOMServer.renderToString(App),
seo: { title: "Home", description: "" }
};
res.render("index", { data });
});
}
但我想生成 .html
文件,这样我就可以静态地为它们提供服务,而无需每次都使用 运行 这种方法。我尝试将 renderToString
的结果编译为 .ejs
文件,然后使用 fs
写入文件,但没有成功。这是代码:
const component = ReactDOMServer.renderToString(App);
const template = ejs.compile(fs.readFileSync(path.join(__dirname, 'landing_template.ejs'), 'utf-8'));
const html = template({ component });
fs.writeFile(
path.join(__dirname, "../views/landing.ejs"),
html,
err => {
if(err) console.log(err);
else console.log("done.");
});
文件写入成功,但如果我打开我的页面源代码,编译方法添加的部分是灰色的,似乎被忽略了:
我也试过只读取文件并使用 .replace
替换字符串并插入一个虚拟 div
,但结果始终相同。
// using compile
const template = ejs.compile(fs.readFileSync(path.join(__dirname, 'landing_template.ejs'), 'utf-8'));
const html = template({ component });
const template = ejs.compile(fs.readFileSync(path.join(__dirname, 'landing_template.ejs'), 'utf-8'));
const html = template({ component: "<div>teste</div>" });
// using readFile
const template = fs.readFileSync(path.join(__dirname, 'landing_template.ejs'), 'utf-8');
const html = template.replace("<%- component %>", component);
const template = fs.readFileSync(path.join(__dirname, 'landing_template.ejs'), 'utf-8');
const html = template.replace("<%- component %>", "<div>teste</div>");
// maybe this is the problem?
fs.writeFile(
path.join(__dirname, "../views/landing.ejs"),
html,
{ encoding: "utf8" },
err => {
if(err) console.log(err);
else console.log("done.");
});
我猜浏览器无法将此新文本识别为 HTML 并且无法解析它。有谁知道我可以做这个的方法吗?
谢谢!
多么酷的主意!这可能是因为,正如您提到的,浏览器没有识别出您正在发送 html 这一事实。在调用 render:
之前尝试将Content-Type
header 显式设置为 text/html
export default (Page) => (req, res) => {
const App = (
<ApolloProvider client={client(fetch)}>
<Main>
<Page />
</Main>
</ApolloProvider>
);
getDataFromTree(App).then(() => {
const data = {
html: ReactDOMServer.renderToString(App),
seo: { title: "Home", description: "" }
};
res.setHeader("Content-Type", "text/html");
res.render("index", { data });
});
}
编辑:
啊,我看到了!不幸的是,您不能在 HTML 中使用 self-close <script>
标签,这会使浏览器出错。像这样关闭 header 中的脚本标签:
<script async src="/build/app.bundle.js" type="text/javascript"></script>
这应该可以解决问题。
<script />
是错误的。你必须使用这个:
<script src="URL"></script>