我正在尝试将对象数组发送到服务器,每个对象包含一个如下所示的base64编码的.png图像:
[
{
itemName: '...',
itemType: '...',
price: 123,
purchaseUrl: '...',
imageBase64: 'data:image/png;base64,...'
},
{...},
{...}
]
我需要的所有数据都将一直保存到创建POST请求的位置,然后所有base64映像都变为空白。
{
"newMerchandise": [
{
"imageBase64":"",
"itemName":"asdasd",
"itemType":"asdsad",
"purchaseUrl":"asdsad",
"price":123
}
],
"artistRef":"eddcc4ec-4e7c-4e0a-916e-3b845d9b713d"
}
发送http请求的Angular Injectable如下所示:
@Injectable()
export class MerchandiseApiService implements MerchandiseApiServiceInterface {
private readonly _http: HttpClient;
constructor(http: HttpClient) {
this._http = http;
}
public addItems(newMerchandise: Array<NewMerchandiseUploadRequestClass>, artistRef: string): Observable<ApiResponse<string>> {
console.log(newMerchandise); // base64 string exists still on each item.
return this._http.post(`${environment.apiUrl}/api/merchandise/add-items`, {
newMerchandise: newMerchandise,
artistRef: artistRef
})
.pipe(
map((response: MusicPortalApiResponse<string>): MusicPortalApiResponse<string> => {
return {
response: response.response,
hasError: response.hasError,
exception: response.exception
}
})
)
}
}
我尝试使用formData做同样的事情,我尝试了一种在将Base64字符串附加到FormData之前对其进行字符串化的方法,该方法可以工作,但随后我进行了如下修改:
"\"imageBase64"\":"\"data:image/png;base64,..."\",
这根本不干净。
我想知道这是否是标题文件?
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 165
Content-Type: application/json
Host: localhost:5000
Origin: http://localhost:4200
Pragma: no-cache
Referer: http://localhost:4200/user/add-new-merchandise/eddcc4ec-4e7c-4e0a-916e-3b845d9b713d?artistRef=eddcc4ec-4e7c-4e0a-916e-3b845d9b713d
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36
X-AUTH-TOKEN: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJjMWM3OWRjNy1hMTdmLTRkNTktODBhNS1kNjM0YWVlNzAzNWYiLCJleHAiOjE1NzM3Mjk1MzMsImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6NTAwMC8iLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjUwMDAvIn0.WTKdP6cFrUGrDq4YnX5IlqOkwP3-YRyhMrNpvQZzIWs
编辑
我已在服务器上的调试器中添加了此屏幕快照,该屏幕显示Base64字符串为空
答案 0 :(得分:0)
所以我没有办法弄清楚发生了什么...但是,我的一个朋友只是建议使用文件上传指令,因此在进行大量重构并消除了cr * p吨的代码之后,我结束了:
import { Directive, ElementRef, forwardRef, HostListener, Renderer2 } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
@Directive({
selector: '[fileUpload]',
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => FileUploadDirective),
multi: true,
}
]
})
export class FileUploadDirective implements ControlValueAccessor {
private _onChange: Function;
private _onTouched: Function;
private readonly _renderer: Renderer2;
private readonly _element: ElementRef;
constructor(renderer: Renderer2, element: ElementRef) {
this._renderer = renderer;
this._element = element;
}
public registerOnChange(fn: Function): void {
this._onChange = fn;
}
public registerOnTouched(fn: Function): void {
this._onTouched = fn;
}
public setDisabledState(isDisabled: boolean): void {
this._renderer.setProperty(this._element.nativeElement, 'disabled', isDisabled);
}
public writeValue(value: any): void {
this._renderer.setProperty(this._element.nativeElement, 'value', value);
}
@HostListener('change', ['$event.target.value'])
public onValueChange(): void {
const file = this._element.nativeElement.files[0];
const fileReader = new FileReader();
fileReader.onload = (result): any => this._onChange(result.target['result']);
fileReader.readAsDataURL(file);
}
}
然后附加到我的文件上传表单输入中:
<div class="my-2">
<div>
<label for="file-input">Choose an item image</label>
<input id="file-input" class="file-input" accept="image/*" type="file" [formControlName]="newMerchandiseFormEnum.ITEM_IMAGE" fileUpload>
</div>
</div>
这也意味着我在FormControl上也不必有任何不合理的逻辑,因此这是双赢。
import {Component, EventEmitter, Input, Output} from '@angular/core';
import {FormControl, FormGroup, Validators} from '@angular/forms';
import {NewMerchandiseFormEnum} from '../../../../models/form-enums/new-merchandise-form.enum';
import {Artist} from '../../../../models/domain/artist.class';
import {NewMerchandiseUploadRequest} from '../../../../models/api/new-merchandise-upload-request.class';
@Component({
selector: 'app-new-merch-form',
templateUrl: 'new-merchandise-form.component.html',
styleUrls: ['new-merchandise-form.component.scss']
})
export class NewMerchandiseFormComponent {
public newMerchandiseForm: FormGroup;
public newMerchandiseFormEnum: typeof NewMerchandiseFormEnum = NewMerchandiseFormEnum;
@Input() public artist: Artist;
@Output() public onFormSubmitted: EventEmitter<NewMerchandiseUploadRequest>;
constructor() {
this.onFormSubmitted = new EventEmitter<NewMerchandiseUploadRequest>();
this.newMerchandiseForm = new FormGroup({
[this.newMerchandiseFormEnum.ITEM_NAME]: new FormControl('', [Validators.required]),
[this.newMerchandiseFormEnum.ITEM_TYPE]: new FormControl('', [Validators.required]),
[this.newMerchandiseFormEnum.ITEM_PRICE]: new FormControl('', [Validators.required]),
[this.newMerchandiseFormEnum.ITEM_IMAGE]: new FormControl(null, [Validators.required]), // It just gets attached here as a string now.
[this.newMerchandiseFormEnum.PURCHASE_URL]: new FormControl('', [Validators.required]),
})
}
public emitNewMerchForm(): void {
this.onFormSubmitted.emit(this.newMerchandiseForm.value);
this.newMerchandiseForm.reset();
}
}