为什么没有节点为我的图像文件服务?

时间:2016-04-15 15:51:04

标签: node.js

我有一个vanilla node.js http服务器。除了我的图像文件以外的所有内容我只是在页面上看到了破碎的图像图标。

这是我的服务器代码:

"use strict";

class app {
     constructor() {
          app.loadServer();
     }

     static loadServer() {
          const HTTP = require('http'),
               PORT = 1337,
               SERVER = HTTP.createServer(function(req, res) {
                    let httpHandler = function(err, str, contentType) {
                         console.log('\n\n' + 'Content type: ' + contentType + '\n\n');
                         if (err) {
                              res.writeHead(500, {'Content-Type': 'text/plain'});
                              res.end('An error has occurred: ' + err.message);
                         } else if (contentType.indexOf('image') >= 0) {
                              res.writeHead(200, { 'Content-Type': contentType });
                              res.end(str, 'binary');
                         } else {
                              res.writeHead(200, { 'Content-Type': contentType });
                              res.end(str);
                         }
                    };

                    if (req.headers['x-requested-with'] === 'XMLHttpRequest') {
                         if (req.method == 'POST') {
                              app.getFormData(req, res);
                         } else {
                              console.log("[405] " + req.method + " to " + req.url);
                              res.writeHead(405, "Method not supported", { 'Content-Type': 'text/html' });
                              res.end('<html><head><title>405 - Method not supported</title></head><body><h1>Method not supported.</h1></body></html>');
                         }
                    } else if (req.url.indexOf('/javascripts/') >= 0) {
                         app.render(req.url.slice(1), 'application/ecmascript', httpHandler);
                    } else if (req.url.indexOf('/css/') >= 0) {
                         app.render(req.url.slice(1), 'text/css', httpHandler);
                    } else if (req.url.indexOf('/images/') >= 0) {
                         app.render(req.url.slice(1), 'image/jpg', httpHandler);
                    } else {
                         app.render('public/views/index.html', 'text/html', httpHandler);
                    }

               }).listen(PORT, function() {
                    console.log('-= Francis Server Listening at http://127.0.0.1:' + PORT + ' =-');
               });
     }

     static render(path, contentType, callback) {
          const FS = require('fs');
          FS.readFile(__dirname + '/' + path, 'utf-8', function(err, str) {
               callback(err, str, contentType);
          });
     }

     static getFormData(req, res) {
          const FORMIDABLE = require('formidable'),
               DO_NAMES = require('./node/NameClass');
          let formData = {};
          new FORMIDABLE.IncomingForm().parse(req)
              .on('field', function(field, name) {
                   formData[field] = name;
              })
              .on('error', function(err) {
                   next(err);
              })
              .on('end', function() {
                   let finalName = new DO_NAMES(formData);
                   res.writeHead(200, {'content-type': 'text/plain'});
                   res.write('-= Received form: ');
                   res.end(finalName.getFirstName() + ' ' + finalName.getLastName());
              });
     }
}

module.exports = app;

感觉就像它试图将图像作为文本而不是图片来提供。我确认图像存在且可读。

2 个答案:

答案 0 :(得分:1)

您的NODE服务器似乎设置了错误的MIME类型。您可以自己设置MIME类型,但这会非常痛苦。我建议使用为此目的而制作的MIME类型节点模块。

http://www.mindrot.org/projects/jBCrypt/

这个npm包只需很少的努力即可完成。

答案 1 :(得分:1)

我发现了问题。

它发生在这里:

FS.readFile(__dirname + '/' + path, 'utf-8', function(err, str) {
    callback(err, str, contentType);
});

您将图像文件读取为UTF-8,但它是二进制文件。这就是图像数据损坏的原因。相反,您必须使用binary作为编码。 您可以像这样更改代码:

static render(path, contentType, callback, encoding) {
    const FS = require('fs');
    FS.readFile(__dirname + '/' + path, encoding ? encoding : 'utf-8', function(err, str) {
        callback(err, str, contentType);
    });
}

然后像这样调用render

app.render(req.url.slice(1), 'image/jpeg', httpHandler, 'binary');

显然有更好的方法,但这需要对代码进行最少量的更改。只需确保二进制文件的readFile()编码为binary

jpg的正确mime类型还有image/jpeg而非image/jpg。大多数(如果不是全部)浏览器都不关心,但它更干净。