#node.js #express #vue.js #heroku
#node.js #экспресс #vue.js #heroku
Вопрос:
Я пытаюсь развернуть Node.js приложение к Heroku. Интерфейс для приложения был написан на Vue.js . Вывод сборки Vue находится /public
в приложении Node. Он отлично работает при запуске localhost
и может быть доступен как https://localhost:8080/public
.
Конечно, это не так на Heroku. X-Content-Type-Options
Заголовок устанавливается их серверами, которые блокируют все CSS и JS файлы, и я получаю это сообщение об ошибке в Chrome:
Refused to apply style from 'https://my-awesome-app.herokuapp.com/css/app.5364ed87.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
Я немного повозился со своими статическими файлами и обнаружил, что не так. В рабочей сборке index.html
содержатся ссылки, подобные этой:
<link href=/js/chunk-109f12d9.3bbd3c2d.js rel=prefetch>
<link href=/js/chunk-2d0bae5c.0ec2a734.js rel=prefetch>
<link href=/js/chunk-2d0f1192.aa2d5399.js rel=prefetch>
<link href=/js/chunk-f8fb7b5a.9218edff.js rel=prefetch>
<link href=/css/app.5364ed87.css rel=preload as=style>
<link href=/js/app.af503387.js rel=preload as=script>
<link href=/js/chunk-vendors.aa1329d3.js rel=preload as=script>
<link href=/css/app.5364ed87.css rel=stylesheet>
Я обнаружил, что если я удалю начальную косую черту из href
атрибутов, ссылки внезапно начнут работать. Так css/whatever.css
работает, /css/whatever.css
не работает.
Я подозреваю, что что-то не так с тем, как я включаю статические каталоги в моей экспресс-настройке. Но я не мог понять, что. У вас есть какие-нибудь идеи?
const publicPath = path.join(__dirname, 'public');
this.express.use('/public', express.static(publicPath));
Добавление косой черты в любом месте или ее удаление не помогает. Я уже перепробовал все возможные комбинации. Это не работает как /public
, /public/
, public/
, public
, и т.д.
Может быть, базовый URL-адрес должен быть установлен в Vue? В настоящее /
время.
Да, я знаю, что есть много вопросов по этому поводу, но нет рабочих ответов.
Ответ №1:
Вы получаете это, потому что сервер не отвечает css, это, скорее всего, html, точнее страница 404, которую браузер фактически идентифицирует как text/html
.
Вот возможные исправления:
-
Проверьте, действительно ли ваше приложение vue создано со всеми файлами js и css (возможно, вы пропустили шаг сборки для приложения vue)
-
Используется
heroku run bash
для проверки ваших файлов после их сборки -
Обслуживайте статические файлы с
/
URL-адресом, но также не допускайте, чтобы другие маршруты не были достигнуты таким образом:app.get('/api/', ......) app.use('/public', express.static(path.join(__dirname, 'public')))
Убедитесь, что статическая настройка является последней.
-
Попробуйте посетить URL-адреса javascript и css непосредственно в вашем браузере, чтобы увидеть, как реагирует сервер
Комментарии:
1. Спасибо, все правильно, но проблема была вызвана интерфейсом. Смотрите мой ответ.
Ответ №2:
Проблема оказалась не серверной, а интерфейсной.
Действительно, проблема была с путями ссылок. Когда Vue сгенерировал их, предполагалось, что приложение будет находиться в корне своего собственного каталога, следовательно, все активы будут находиться под /
. Но вместо этого они были под /public
. Поэтому, когда Express пытался обслуживать статические файлы, index.html
он был в нужном месте, но он пытался найти CSS и другие ресурсы под /css
, а не /public/css
. По какой-то причине это вызвало не ошибку 404, а несоответствие типа MIME.
Решение состоит в том, чтобы изменить общедоступный путь в Vue. Создайте vue.config.js
файл в корне проекта и добавьте:
module.exports = {
publicPath: "/public/"
}
Теперь ссылки на ресурсы будут сгенерированы, /public/css
и интерфейс будет работать.
Обратите внимание, что ./
это не работает, потому что Vue не добавит его, а полностью опустит путь. Завершающая косая черта не важна, Vue добавит ее, если вы этого не сделали.
Вот пошаговая запись, если хотите: https://medium.com/developer-rants/why-is-strict-mime-type-checking-blocking-the-static-serving-of-vue-frontend-files-4cbea1eedbd1