Браузер принимает «классический» скрипт-тег js, но не модули ES6 - ошибка MIME с сервером http узла - PullRequest
0 голосов
/ 12 февраля 2019

Я хочу поиграть с модулями ES6, поэтому я решил использовать Node в качестве простого веб-сервера, чтобы избежать всех ошибок, связанных с CORS, с которыми я впервые столкнулся, когда делал это локально.Теперь в браузере появляются ошибки, связанные с MIME-типами, которые я не могу понять.

Вот мой файл server.js:

const http = require('http'),
      url  = require('url'),
      fs   = require('fs');

http.createServer((req, res) => {

  const q = url.parse(req.url, true),
        filename = "." + q.pathname;

  fs.readFile(filename, (err, data) => {
    if (err) {
      res.writeHead(404, {'Content-Type': 'text/html'});
      return res.end("404 Not Found");
    }  
    res.writeHead(200, {'Content-Type': 'text/html'});
    res.write(data);
    return res.end();
  });

}).listen(8080);

Если я пытаюсь получить доступ к своему index.htmlфайл в браузере, который содержит следующий код:

<!DOCTYPE html>
<html>
<body> 

  <!-- Works -->
  <script src="index.js"></script>

  <!-- Doesn't work -->
  <script src="module.js" type="module"></script>

</body>
</html>

Я получаю следующую ошибку:

Не удалось загрузить скрипт модуля: сервер ответил с MIME не-JavaScriptтип "text / html".

Атрибут type="text/javascript" также не влияет на тег модуля.Я прочитал, что все модули ES6 по умолчанию «отложены», что означает, что они не выполняются до полного разбора HTML.Я думаю, что это проблема, но я не знаю, как изменить мой файл server.js соответственно, чтобы исправить это.Помощь очень ценится!Если не слишком непрактично, я бы предпочел не загружать какие-либо пакеты NPM.

РЕДАКТИРОВАТЬ: Я думал, что так как я получил доступ к http://localhost:8080/index.html То, что было правильно отправлять заголовок с типом text/html.Но если я console.log(url.parse(req.url, true));, то теперь я вижу, что теги отложенного сценария вызывают обратный вызов createServer.Зарегистрированный объект явно показывает, что это имя файла модуля JS.

Я вернусь с рабочим примером, как только исправлю неисправный заголовок.

РЕШЕНИЕ: Я вытащил два дополнительных модуля;путь и мим .Я использовал mime.getType() для расширения пути, возвращаемого url.parse().

const http = require('http'),
      url  = require('url'),
      fs   = require('fs'),
      mime = require('mime'),
      path = require('path');

http.createServer((req, res) => {

  const q = url.parse(req.url, true),
        filename = "." + q.pathname;

  fs.readFile(filename, (err, data) => {
    if (err) {
      res.writeHead(404, {'Content-Type': 'text/html'});
      return res.end("404 Not Found");
    }  
    res.writeHead(200, {'Content-Type': mime.getType(path.extname(filename))});
    res.write(data);
    return res.end();
  });

}).listen(8080);

Ответы [ 2 ]

0 голосов
/ 12 февраля 2019

Вы отправляете обратно заголовок Content-Type: text/html, когда браузер запрашивает ваш модуль - это неверно, согласно спецификации HTML :

Если какой-либо извыполняются следующие условия, выдается исключение DOMExror "NetworkError":

  • response имеет тип "error"
  • response статус не является нормальным
  • Результатом извлечения MIME-типа из списка заголовков ответа не является MIME-тип JavaScript

'Classic' scripts don 'Насколько я могу судить, у этого ограничения нет.

Чтобы это исправить, вам необходимо отправить свой модуль JavaScript обратно с сервера с соответствующим типом MIME, например text/javascript:

res.writeHead(200, {'Content-Type': 'text/javascript'});

Я бы рекомендовал использовать что-то вроде Express вместо непосредственной работы с модулем http, хотя - вы можете получить много этой функциональности из коробки , и я верю в этоРазберусь с настройкой заголовков.

0 голосов
/ 12 февраля 2019
res.writeHead(200, {'Content-Type': 'text/html'});

Это предполагает, что каждый файл обслуживается с text/html mimetype.

...