首页 > 解决方案 > 使用多部分文件和 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
    });
};

我应该怎么办?

标签: javascriptajaxreactjsspring

解决方案


好的,我找到了解决方案: 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));
}

推荐阅读