[英]Node itself can serve static files without express or any other module..?
我是节点 js 领域的初学者。不知道如何从 url 发送简单请求,例如:- http://localhost:9999/xyz/inde.html我的文件层次结构是
server.js
xyz(folder)-
|->index.html
并从我的服务器获取 html 页面。它在 9999 后运行
var http = require("http");
function onRequest(request, response) {
console.log("Request received.");
response.writeHead(200, {"Content-Type": "text/plain"});
response.end();
}
http.createServer(onRequest).listen(9999);
console.log("Server has started.");
我知道我可以从节点 js 服务器发送字符串(具有 html 模板)并发送它作为响应,但是如何在没有 express 和任何其他外部模块的情况下发送文件。 谢谢
尝试创建一个没有npm
依赖项的节点应用程序是荒谬的,因为 nodejs 的基础就是——一个基础。 除非你想实现整个协议,否则最好使用一个最小的、维护良好的npm
模块来为你做这npm
。 也就是说,这是您要求的非常基本的东西(没有 MiME、eTags、缓存等):
var basePath = __dirname;
var http = require('http');
var fs = require('fs');
var path = require('path');
http.createServer(function(req, res) {
var stream = fs.createReadStream(path.join(basePath, req.url));
stream.on('error', function() {
res.writeHead(404);
res.end();
});
stream.pipe(res);
}).listen(9999);
const http = require('http'); const fs = require("fs"); const path = require("path"); function send404(response){ response.writeHead(404, {'Content-Type': 'text/plain'}); response.write('Error 404: Resource not found.'); response.end(); } const mimeLookup = { '.js': 'application/javascript', '.html': 'text/html' }; const server = http.createServer((req, res) => { if(req.method == 'GET'){ let fileurl; if(req.url == '/'){ fileurl = 'index.html'; }else{ fileurl = req.url; } let filepath = path.resolve('./' + fileurl); let fileExt = path.extname(filepath); let mimeType = mimeLookup[fileExt]; if(!mimeType) { send404(res); return; } fs.exists(filepath, (exists) => { if(!exists){ send404(res); return; } res.writeHead(200, {'Content-Type': mimeType}); fs.createReadStream(filepath).pipe(res); }); } }).listen(3000); console.log("Server running at port 3000");
它非常简单,节点已经提供了 fs 模块,您可以从中读取该 html 文件并附加在响应 obj 上,如下所示:
response.writeHead(200, {"Content-Type": "text/plain"});
//here is the code required
fs.readFile("./xyz/index.html", (err,fileContent) =>
{
response.end(fileContent);
});
但这里的问题是你只会得到 HTML 文档,而不是那些存储在不同文件夹中的 HTML 文件中的资源,就像你的 index.html 中有这个代码一样
<link rel="stylesheet" href="../css/index.css" />
节点服务器将不允许此 index.css。 但我想你的问题已经解决了。
我不同意接受的答案中的断言:
“尝试创建一个没有 npm 依赖项的节点应用程序是荒谬的”
由于具有零依赖项,因此您只需复制 javascript 文件即可将应用程序部署到运行 node 的系统,而无需运行npm install
。
我发现这在现实生活中很有用的一个例子是编写一个公共 API 来计算企业需要从员工工资中扣除的所得税金额。 你可以在这里阅读关于这个有趣话题的所有内容,但本质上我有一个 api,它通过了总收入并返回了总收入应如何在净收入和税收之间分配。
我用一个单独的 index.js 文件做到了这一点,没有 package.json,并且需要npm install
:
索引.js:
http = require('http');
url = require('url');
const port = 80; // make this a number over 1024 if you want to run `node` not run `sudo node`
const debug = true;
const httpServer = http.createServer((request, response) => {
response.setHeader('Content-Type', 'application/json');
const parsedUrl = url.parse(request.url, true);
let pathName = parsedUrl.pathname;
if (pathName==='/favicon.ico') {
// chrome calls this to get an icon to display in the tab. I want to ignore these request. They only happen when testing in a browser,
// not when this api is called in production by a non-browser.
if (debug) console.log('Browser requested favicon.ico')
response.end();
} else {
if (debug) console.log('Request on path ' + pathName);
const elements = pathName.split('/');
if (elements.length == 3 && elements[0] === '' && elements[1]==='witholdcalc') {
const grossString = elements[2];
const gross = Number.parseInt(grossString);
if (isNaN(gross)) {
response.writeHead(400).end(JSON.stringify({error:'Gross salary must be an integer. found: ' + grossString}));
} else {
/*
* The computation of the amount to withold is more complicated that this, but it could still be hard coded here:
* For simplicity, I will compute in one line:
*/
const withold = Math.floor((gross<1000)?0:((gross-1000)*.2));
response.writeHead(200).end(JSON.stringify({net: (gross-withold), withold: withold, elements:(debug?elements:undefined)}));
}
} else {
if (debug) console.log('Invalid path was: ' + pathName,elements);
response.writeHead(404).end();
}
}
});
httpServer.listen(port), () => {
console.log(`PAYG listening at http://localhost:${port}`)
}
然后我可以在我的 linux 计算机上执行sudo node install.js
,并在浏览器中,点击http://localhost/witholdcalc/6000
,它会在调试时返回 {"net":5000,"withold":1000}设置为假。
任何试图在没有 Express 或任何其他框架的情况下提供静态文件的人,请注意:
在性能或生产力方面,跳过 Express 没有任何好处。 唯一的例外是了解服务器和客户端如何相互通信。 像 Express 这样的框架抽象了所有这些复杂性,初学者可能无法完全理解它们的工作原理。
这是我仅使用 Node.js 提供静态文件的方法。 实际上,我这样做的原因是因为给我的编码测试没有规定任何框架。
首先,决定这些静态文件的 URL 路径应该是什么样的。 我希望我的可以在/assets/
路径下访问,例如https://example.com/assets/main.css
, https://example.com/assets/cat.jpg
。
决定匹配这些 URL 的 REGEX。 `const assetPattern = /^/assets/[a-zA-Z]+.[a-zA-Z]+/;
上面的公式将匹配包含/assets/[filename].[file extension
url。
// ...
const http = require('http')
const server = http.createServer(requestListener).
const path = require('path');
// ...
const requestListener = (req, response) => {
// get the relative url for the request. For example, relative url for a request
// to https://example.com is /.
const { url } = req;
if (url.match(assetPattern)) {
// Inside the project directory, the static files are located under the
// /public/assets directory.
const filePath = `./public/${url}`;
// Get the extension name aka the string after the dot. For example, a url like
// https://example.com/assets/main.css will result in extension name of css.
const extname = String(path.extname(filePath)).toLowerCase();
const mimeTypes = {
'.html': 'text/html',
'.js': 'text/javascript',
'.css': 'text/css',
'.json': 'application/json',
'.png': 'image/png',
'.jpg': 'image/jpg',
'.gif': 'image/gif',
'.svg': 'image/svg+xml',
'.wav': 'audio/wav',
'.mp4': 'video/mp4',
'.woff': 'application/font-woff',
'.ttf': 'application/font-ttf',
'.eot': 'application/vnd.ms-fontobject',
'.otf': 'application/font-otf',
'.wasm': 'application/wasm',
};
const contentType = mimeTypes[extname] || 'application/octet-stream';
staticFileHandler(req, response, filePath, contentType);
}
}
fs
模块提供静态文件const fs = require('fs')
// ...
const staticFileHandler = (req, res, filePath, contentType) => {
fs.readFile(filePath, (err, content) => {
if (err) {
res.writeHead(500);
res.end(`Sorry, check with the site admin for error: ${err.code}`)
} else {
res.writeHead(200, { 'Content-Type': contentType }); // indicate the request was successful
res.end(content, 'utf-8');
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.