Поэтому я пытаюсь отправить файл в корзину Amazon S3, используя стандартный метод Angular HTTP POST.
Вот код вопроса:
public postFileToS3(file: File, params: any, url: string): Observable<any> {
const headers = new HttpHeaders(params);
headers.set('enctype', 'multipart/form-data');
const formData = new FormData();
formData.append('file', file);
formData.append('Content-Type', file.type);
formData.append('key', file.name);
formData.append('name', file.name);
formData.append('enctype ', 'multipart/form-data');
Object.keys(params).forEach(key => {
formData.append(key, params[key]);
});
return this.http.post(url, formData, {headers: headers});
}
И переданы ему параметры доступа, полученные от S3, и файл, который я пытаюсь отправить:
private uploadFile(file: File, fileNames: string[], masterProjectId: number): void {
const reader = new FileReader();
if (!this.supportedMimeTypes.test(file.type)) {
return this.informAboutErrors();
}
reader.onprogress = this.onProgressHandler();
reader.onload = () => {
fileNames.push(file.name);
this.api.getS3FormData(file.type, masterProjectId).subscribe((response) => {
const s3Directory = [this.api.getDirectory(file.type)];
const inputs = response['inputs'];
const key = (s3Directory.length ? s3Directory.join('/') + '/' : '') + file.name;
this._url = response['url'];
this._uploadParams['Content-Type'] = file.type;
this._uploadParams['acl'] = inputs['acl'];
this._uploadParams['success_action_status'] = inputs['success_action_status'];
this._uploadParams['policy'] = inputs['policy'];
this._uploadParams['X-amz-credential'] = inputs['X-amz-credential'];
this._uploadParams['X-amz-algorithm'] = inputs['X-amz-algorithm'];
this._uploadParams['X-amz-date'] = inputs['X-amz-date'];
this._uploadParams['X-amz-expires'] = inputs['X-amz-expires'];
this._uploadParams['X-amz-signature'] = inputs['X-amz-signature'];
this._uploadParams['key'] = key;
if (response) {
this.api.postFileToS3(file, this._uploadParams, response['url']).subscribe(data => console.log(data));
}
});
};
if (file) {
reader.readAsText(file);
}
}
Так что теоретически все должно работать нормально, я прошел проверку подлинности и отправляет POST, но я получаю ошибку 412 - «Precondition Failed» с сообщением об ошибке «По крайней мере одно из указанных вами предварительных условий выполнено» не удерживается. Ведро POST должно иметь тип multipart / form-data типа ".
Я пытался установить "enctype" как для заголовков, так и для FormData, но безуспешно. Также вот полный запрос от Chrome Dev Tools:
Provisional headers are shown
Accept: application/json, text/plain, */*
acl: private
Content-Type: audio/mp3
key: voice_tests/sample.mp3
Origin: https://localhost:4200
policy:xxx
Referer: https://localhost:4200/app/casting-setup/7782/29867
success_action_status: 201
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36
X-amz-algorithm: xxx
X-amz-credential: xxx
X-amz-date: xxx
X-amz-expires: xxx
X-amz-signature: xxx
Похоже, в FormData нет файла и, возможно, в этом проблема. Я также обнаружил некоторую проблему с GitHub в репозитории Angular, когда некоторые говорили, что отправка FormData с этим enctype также не работает для них.
Я буду признателен за любую помощь, которую я могу получить. Я знаю, что есть отличный пакет aws-sdk, но сейчас я должен сделать это следующим образом.
Спасибо