节点本身可以​​提供静态文件而无需快递或任何其他模块..?

时间:2015-01-21 06:43:03

标签: node.js

我是节点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和任何其他外部模块。 感谢

5 个答案:

答案 0 :(得分:7)

尝试创建没有npm依赖关系的节点应用程序是荒谬的,因为nodejs的基础就是 - 基础。除非您想要实现整个协议,否则最好使用最小的,维护良好的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);

答案 1 :(得分:1)



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");




答案 2 :(得分:1)

我不同意接受的答案中的断言:

“尝试创建没有npm依赖性的节点应用程序是荒谬的”

由于零依赖关系使您可以通过仅复制javascript文件而不运行npm install来将应用程序部署到运行节点的系统。

当我发现这在现实生活中很有用时,一个示例是编写一个公共API来计算企业需要从雇员的工资中扣除的所得税额。您可以阅读有关fascinating topic here的全部信息,但从本质上讲,我有一个api,该API传递了总收入并返回了如何在净收入和税金之间分配总收入。

我使用一个单独的index.js文件(没有package.json)来完成此操作,并且需要npm install

index.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}为假。

答案 3 :(得分:0)

它非常简单,节点已经提供了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。 但我想你的问题已经解决了。

答案 4 :(得分:0)

针对任何试图在没有Express或任何其他框架的情况下提供静态文件的人进行提示:

就性能或生产力而言,跳过Express没有任何好处。唯一的例外是要了解服务器和客户端之间如何通信。 Express之类的框架消除了所有这些复杂性,并且初学者可能无法完全理解它们的工作原理。

这是我仅使用Node.js来提供静态文件的方法。实际上,我这样做的原因是因为给我的编码测试没有规定任何框架。

  1. 首先,确定这些静态文件的URL路径应为什么样。我希望我的用户可以在/assets/路径下访问,例如https://example.com/assets/main.csshttps://example.com/assets/cat.jpg

  2. 确定用于匹配这些URL的REGEX。 `const assetPattern = / ^ / assets / [a-zA-Z] +。[a-zA-Z] + /;

上面的公式将匹配包含/assets/[filename].[file extension的网址。

  1. 使用回调函数作为参数,使用Node.js创建服务器。
// ...
const http = require('http')
const server = http.createServer(requestListener).
  1. 提取URL路径,获取相应的文件路径,并将您的服务器配置为将正确的MIME类型发送到浏览器。
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);
  }
}
  1. 使用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');
    }
  }
}