У меня странная ошибка, и я не знаю, почему Node.js не видит URL-адрес и всегда возвращает мне 404.
В приложении Vue.js я делаю почтовый запрос с пакетом axios, когда пользователь нажимает кнопку. Как видно из кода, я отправляю имя файла в теле запроса и токен пользователя в заголовке. Я проверяю, и оба значения не пусты.
getFile (fileName) {
axios.post('/csv', {file_name: fileName}, {headers: {'Authorization': this.token}}).then(response => {
console.info(response)
this.showAlert('File successfully downloaded.', 'is-success', 'is-top')
}).catch((error) => {
console.info(error)
this.showAlert('An error occurred while downloading the file.', 'is-danger', 'is-bottom')
})
}
ОШИБКА:
Error: Request failed with status code 404
at FtD3.t.exports (createError.js:16)
at t.exports (settle.js:18)
at XMLHttpRequest.f.(:3010/anonymous function) (http://localhost:3010/static/js/vendor.1dc24385e2ad03071ff8.js:1312:88758)
Все запросы из браузера идут на HTTP-сервер в Node.js (Express.js). В моем случае файл csv.js должен обрабатывать запрос. Я не понимаю, в какой части проекта проблема. Кстати, другие URL-адреса работают правильно.
сервер/bin/www.js:
/**
* Module dependencies.
*/
const app = require('../../app')
const debug = require('debug')('slot:http-server')
const http = require('http')
/**
* Get port from environment and store in Express.js.
*/
let port = normalizePort(process.env.PORT || '3010')
app.set('port', port)
/**
* Create HTTP server.
*/
const server = http.createServer(app)
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port)
server.on('error', onError)
server.on('listening', onListening)
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort (val) {
const port = parseInt(val, 10)
if (isNaN(port)) {
return val
}
if (port >= 0) {
return port
}
return false
}
/**
* Event listener for HTTP server "error" event.
*/
function onError (error) {
if (error.syscall !== 'listen') {
throw error
}
const bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges')
process.exit(1)
break
case 'EADDRINUSE':
console.error(bind + ' is already in use')
process.exit(1)
break
default:
throw error
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening () {
const address = server.address()
const bind = typeof address === 'string' ? 'pipe ' + address : 'port ' + address.port
debug('Listening on ' + bind)
}
приложение.js:
const express = require('express');
const cookieParser = require('cookie-parser');
const logger = require('morgan');
const cors = require('cors');
const path = require('path');
const locationsRouter = require('./server/routes/locations');
const csvRouter = require('./server/routes/csv');
const app = express();
app.use(cors());
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({extended: false}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'dist')));
app.use('/api/locations', locationsRouter);
app.use('/csv', csvRouter);
module.exports = app;
сервер/маршруты/csv.js:
const express = require('express')
const router = express.Router()
const fs = require('fs')
const path = require('path')
let Client = require('ssh2-sftp-client')
let sftp = new Client()
const config = require('../config')
router.post('/', (req, res) => {
// Set the variable with the name of the file.
const fileName = req.body.file_name
// Path to file in remote SFTP server.
const remotePath = '/reports/' + fileName
// Local directory where the downloaded file will be placed
const localePath = path.join(process.env.HOME || process.env.USERPROFILE, 'downloads/' + fileName)
// Connect to remote SFTP server.
sftp.connect(config.sftpServer, 'on').then(() => {
// Download file from remote SFTP server to local machine of the user.
sftp.fastGet(remotePath, localePath, {}).then(() => {
res.setHeader('Content-disposition', 'attachment; filename=' + fileName)
res.sendFile(localePath)
fs.unlink(localePath)
}).catch((error) => {
console.info(error)
})
}).catch((error) => {
console.info(error)
})
})
module.exports = router
Что можете посоветовать ребята?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


В vue вы делаете почтовый запрос в /csv, но в вашем app.js вы определяете маршрут /csv как GET, это ваша проблема: D
ОБНОВИТЬ
Если вы хотите, чтобы это работало с загрузкой анимации, такой как хром Взгляните на эту ссылку https://gist.github.com/javilobo8/097c30a233786be52070986d8cdb1743
Что ж, если я поменяю router.get на router.post, Node.js вызовет ошибку: Error: Request failed with status code 500. Можете ли вы проверить мой файл csv.js и сказать, что не так?
Я меняю свой файл csv.js. Можете ли вы проверить мой пост еще раз, пожалуйста. Мне нужно отправить загруженный файл в качестве ответа.
Какую ошибку вы получаете в console.info?
Метод fastGet, который вы можете увидеть в файле загрузки файла csv.js с удаленного SFTP-сервера на локальный компьютер пользователя. Мне нужно отправить этот файл в ответ на браузер. Можно ли его отправить? Итак, что мне нужно изменить в коде Vue.js?
замените свой код stfp этим и попробуйте, работает ли он.
return sftp.connect(config.sftpServer).then(() => { return sftp.fastGet(remotePath, localePath); }) .then((data) => { res.setHeader('Content-disposition', 'attachment ;имя_файла=' + имя_файла) res.end(данные) }
@PedroSilva позвольте мне попытаться объяснить проблему. Например, когда пользователь хочет загрузить что-то из браузера, он обычно видит, что файл загружается внутри браузера (например, в нижней части Chrome). Я хочу такого же поведения. Прямо сейчас мой код и ваш код загружают файл с удаленного сервера на локальный компьютер пользователя в бэкэнде, и пользователь не может видеть поведение, которое я описал вам ранее. Конечно, я могу показать пользователю сообщение о том, что файл успешно загружен, но ему/ей придется выполнить дополнительные действия, чтобы найти этот файл.
Я думаю, мне нужно изменить код Vue.js. Возможно ли в Vue.js открыть файл из файловой системы или загрузить его?
Давайте продолжить обсуждение в чате.
Просто хочу опубликовать то же самое :+1: