Я унаследовал (не унаследовал ООП, унаследовал бывший сотрудник) некоторый код загрузки файла, который работает, но имеет несколько архитектурных проблем, включая жестко заданные пути к файлам. Проблема в том, что даже после прочтения документации по multer и просмотра нескольких примеров я не до конца понимаю, откуда multer получает файл, имя файла, и особенно путь к файлу на уровне API.
Раньше это был один гигантский блок кода, скопированный в случае необходимости (вздох), который я преобразовал в сервис для инъекций:
mycomponent.component.ts:
// called on click of an 'upload' button in a form on my template
this.uploadService.uploadSingleFile(event.target.files, '/test_uploads_service');
upload.service.ts:
@Injectable()
export class UploadService {
constructor(private http: HttpClient) { }
uploadSingleFile(file_list, file_path) {
const authToken = localStorage.getItem('id_token');
const fileList: FileList = file_list;
if (fileList.length > 0) {
const file: File = fileList[0];
const fname = Date.now() + file.name;
const formData: FormData = new FormData();
formData.append('uploadFile', file, fname );
const headers = new HttpHeaders().set('Authorization', authToken);
this.http.post(`${ environment.apiUrl + '/upload/upload_single'}`, formData, {headers: headers})
.map(res => res)
.catch(error => Observable.throw(error))
.subscribe(error => console.log(error));
}
}
}
Код снова работает для успешной загрузки файла, но здесь есть более загадочный бит в API:
upload.js:
router.post('/upload_single', passport.authenticate('jwt', {session: false}), (req, res) => {
let storage = multer.diskStorage({
destination: function (req2, file, cb) {
cb(null, '../public_html/uploads/test_uploads/');
},
filename: function (req2, file, cb) {
cb(null, file.originalname);
}
});
let upload = multer({storage: storage}).single('uploadFile');
upload(req, res, (err) => {
if (err) {
logger.error(err);
res.json({success:false, message: 'Failed to upload image' + err});
}
else {
res.json({success:true, message: 'Image uploaded successfully'});
}
});
});
Как получить доступ к file_path ('/ test_uploads_service'), который
компонент передан в сервис и используется для установки destination
? Я хотел бы покончить с
жестко запрограммированное значение ('../public_html/uploads/test_uploads/') и использовать
переменная file_path вместо.
Я не понимаю, как анонимная функция, которая устанавливает имя файла diskStorage, даже работает. Без чтения req.file
, который, согласно утверждениям multer docs, нужно добавить к req
, эта новая анонимная функция магически знает значение свойства originalname
... Как это произошло?
Какие-либо другие улучшения, которые можно внести в код в upload.js? Я планирую изменить служебный код, чтобы разрешить загрузку нескольких файлов, но удаление всех жестко закодированных путей является приоритетом.