Необычные различия между res.sendFile (файл) и express.static (файл) - PullRequest
0 голосов
/ 25 сентября 2019

Я создаю веб-приложение, в котором я могу просто загрузить несколько проектов виртуальной реальности Three.js, которые я создал, и отправить их в браузер.

Когда я начал делать это, я провел быструю проверку своей папки VR, чтобы проверить, возможно ли это.Код работал, и поэтому я начал тратить много времени на разработку приложения.Код, который я использовал, выглядит следующим образом:

app.use('/', express.static('/Users/virtuload-beta/backend/uploads/065fe1658b1374605f31d100eb1e7a1a1568654427336/Nancy_Collins_118226967_v2/'))

Это сработало просто отлично, и браузер отобразил мою VR-сцену.Я также хотел убедиться, что файл может быть обработан динамически (например, пользователь щелкает по какой VR-сцене для рендеринга с href, ведущим к URL-адресу), поэтому я выполнил следующий код, который также работал нормально:

const filepath = '065fe1658b1374605f31d100eb1e7a1a1568654427336/Nancy_Collins_118226967_v2/'
app.use('/', express.static(`/Users/virtuload-beta/backend/uploads/${filepath}`))

Я в основном закончил приложение сейчас, за исключением того, что у меня есть огромная проблема, когда я обслуживаю папки VR с указанным файлом index.html (что вам нужно сделать с res.sendFile), браузер не может читать файлы в папках иЯ просто получаю красные ошибки.

Моя функция больше не служит ей как статический файл, она получает идентификатор из URL-адреса, находит путь к файлу из mongodb следующим образом:

const servepath = (req, res, next) => {
    let id = req.params.id
    Upload.findById(id)
      .populate('Upload')
      .select('relPath') //relPath = /folder/subfolder
      .exec(function (err, upload) {
        if (err) {
          res.send(err)
          console.log(err)
        } else {
          const dir = path.join(__dirname, '..', '../vr/uploads')
          const filepath = `${upload.relPath}`
          const fulldir = path.join(dir, filepath)
          console.log(fulldir)
              try {
                    res.sendFile('index.html', {root: `${fulldir}`});

                }
              }
              catch (e) {
                console.error(e)
              }
          // return next();
        }
      })
}

Браузер находитhtml-файл, но не может проанализировать с ним JS-файлы:

GET http://localhost:3000/api/5d8b74be2af25086ab77fef7/js/three.js net :: ERR_ABORTED 404 (не найдено) vr: 21 GET http://localhost:3000/api/5d8b74be2af25086ab77fef7/js/OrbitControls.js net :: ERR_ABORTED404 (не найдено) vr: 22 GET http://localhost:3000/api/5d8b74be2af25086ab77fef7/js/GLTFLoader.js net :: ERR_ABORTED 404 (не найдено) vr: 23 GET http://localhost:3000/api/5d8b74be2af25086ab77fef7/js/FBXLoader.js net :: ERR_ABORTED 404 (Not Found) vr: 24 GET http://localhost:3000/api/5d8b74be2af25086ab77fef7/js/inflate.min.js net :: ERR_ABORTED 404 (не найдено) vr: 25 GET http://localhost:3000/api/5d8b74be2af25086ab77fef7/js/WebGL.js net :: ERR_ABORTED 404 (не найдено) vr: 118 GET http://localhost:3000/api/5d8b74be2af25086ab77fef7/MainScene.js net :: ERR_ABORTED 404 (не найдено)

Когда я жестко запрограммировал путь к файлу в первой строке кода, который я указал здесь (express.static), виртуальная машина рендеринга отлично ... Я пытался использовать файлы как статические файлы, но вы не можете сделатьчто динамически, отсюда и название «статические» файлы .. кто-нибудь знает, почему это происходит?

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

1 Ответ

1 голос
/ 25 сентября 2019

Ваш обработчик servepath, очевидно, обрабатывает запросы на GET /api/:id.Когда браузер получает содержимое index.html, соответствующее параметру id, он, вероятно, находит ссылки, выраженные в виде относительных путей, таких как <script src="js/three.js">.Чтобы создать полностью квалифицированный адрес этого ресурса, он использует местоположение текущего файла.Который, в случае index.html, который вы показываете, кажется http://localhost:3000/api/5d8b74be2af25086ab77fef7.

(довольно) быстрый способ исправить это было бы:

  • выставить вашпроекты статически (с express.static в общей папке для всех ваших загрузок, которые, очевидно, заканчиваются /vr/uploads сейчас)
  • затем, вместо того, чтобы обслуживать index.html непосредственно из /api/:id, используйте этот маршрут какперенаправление на правильное статическое местоположение

Что-то в этом роде:

// expose all uploads, under the URL http://localhost:3000/uploaded-projects/*
app.use(
  '/uploaded-projects',
  express.static(path.join(__dirname, '../../vr/uploads'))
);
// handler to match a Mongo project ID with a public path under /uploaded-projects
app.get(`/api/:id`, (req, res) => {
  Upload.findById(req.params.id)
  .populate('Upload')
  .select('relPath')
  .exec((err, data) => {
    // ko: explicitly use an HTTP status otherwise it's 200
    if (err) return res.status(500).send(err);
    // ok: tell browser 302 + proper Location header
    res.redirect(`/uploaded-projects/${data.relPath}/index.html`);
  });
});

Приложив немного больше усилий, вы можете изменить свой интерфейс, чтобы вместо использования идентификаторав своем списке проектов вы используете relPath (который вы можете предоставить внешнему интерфейсу, поскольку вы уже предоставили идентификаторы, а этот relPath находится внутри документа Mongo) и жестко заданный путь к статическому дереву (вмой эскиз, /uploaded-projects).Это позволит внешнему интерфейсу напрямую создавать правильный URL-адрес, следовательно, избегая обращения к серверу за 302, и вы сможете избавиться от этого /api/:id маршрута.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...