javascript - 使用多部分文件和 json 数据响应 ajax 请求
问题描述
我有一个这样的基本请求:
export const request = (options) => {
const headers = new Headers({
'Content-Type': 'application/json',
});
if (Common.getToken()) {
headers.append('Authorization', 'Bearer ' + Common.getToken())
}
const defaults = {headers: headers};
options = Object.assign({}, defaults, options);
return fetch(options.url, options)
.then(response =>
response.json().then(json => {
if (!response.ok) {
return Promise.reject(json);
}
return json;
})
);
};
和我的ajax请求:
onCreateNewPost(postDataRequest, photoBody) {
const formData = new FormData();
formData.append('photo', photoBody);
formData.append('postData', JSON.stringify(postDataRequest));
return request({
url: API_BASE_URL + '/posts/new-post',
method: 'POST',
body: formData
});
};
其中 postDataRequest - json 对象包括帖子标题、描述等... photoBody - 图像文件。在后端我有一个控制器的方法:
@PostMapping(value = "/api/posts/new-post")
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity createNewPost(@CurrentUser UserPrincipal currentUser,
@RequestBody NewPostDataRequest postRequest,
@RequestParam MultipartFile photo) {
// method body
return ResponseEntity.ok(new ActionCompleteResponse(true));
}
但是当我发送请求时,我得到状态码:400。有什么问题?我可以单独发送 json 数据或多部分数据,但我不知道如何将它们与一个请求一起传输。我试图在请求中放入没有 Content-Type 的标头,如下面的代码所示,以便请求本身指示它,但作为响应,我得到代码 415。
onCreateNewPost(postDataRequest, photoBody) {
const formData = new FormData();
formData.append('photo', photoBody);
formData.append('postData', JSON.stringify(postDataRequest));
const headers = new Headers({});
if (Common.getToken()) {
headers.append('Authorization', 'Bearer ' + Common.getToken());
}
return request({
url: API_BASE_URL + '/posts/new-post',
headers: headers,
method: 'POST',
body: formData
});
};
我应该怎么办?
解决方案
好的,我找到了解决方案: 1.清除标头数据(授权令牌除外) 2.添加到@PostMapping consumes = MediaType.MULTIPART_FORM_DATA_VALUE 并将@RequestPart 添加到方法参数
ajax 请求如:
onCreateNewPost(postDataRequest, photoBody) {
const formData = new FormData();
formData.append('post', new Blob([JSON.stringify(postDataRequest)], {
type: "application/json"
}));
formData.append('photo', photoBody);
const headers = new Headers({});
if (Common.getToken()) {
headers.append('Authorization', 'Bearer ' + Common.getToken())
}
return request({
url: API_BASE_URL + '/posts/new-post',
method: 'POST',
headers: headers,
body: formData
});
};
和弹簧控制器一样
@PostMapping(value = "/new-post", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@PreAuthorize("hasRole('USER')")
public ResponseEntity createNewPost(@CurrentUser UserPrincipal currentUser,
@RequestPart("post") @Valid PostEntity post,
@RequestPart("photo") @Valid MultipartFile photo) throws IOException {
post.setAuthor(currentUser.getUsername());
post.setAuthorId(currentUser.getId());
post.setCommentsCount(0L);
post.setDate(LocalDate.now());
post.setPhoto(photo.getBytes());
postService.save(post);
return ResponseEntity.ok(new ActionCompleteResponse(true));
}