首页 > 解决方案 > 角度文件上传到 micronaut 休息 api 403 错误

问题描述

我正在尝试将多个文件上传到 micronaut Rest API。使用 postman 和 swagger,文件上传在 Micronaut Rest API 中运行良好,但是,使用 Angular 应用程序的 post 方法抛出 403 http 错误。

Micronaut 控制器方法

@Secured(SecurityRule.IS_AUTHENTICATED)
@Post(consumes = MediaType.MULTIPART_FORM_DATA, produces = MediaType.APPLICATION_JSON)
 public Maybe<HttpResponse<?>> post(Publisher<CompletedFileUpload> images) {
            return this.iGoogleCloudService.uploadObject(images).flatMap(item -> {
               if (item.size() > 0)
                   return Maybe.just(HttpResponse.created(item));
               else
                   return Maybe.just(HttpResponse.serverError(ConstantValues.TAG_FALLBACK));
            });
    }

角应用

HTML

<div class="drop-zone w-75" file-drop (files)="onSelectFile($event)"
    [ngClass]="{'disableDiv': dragDropDisable}">
    <svg class="icon" xmlns="http://www.w3.org/2000/svg" width="50" height="43" viewBox="0 0 50 43">
      <path
        d="M48.4 26.5c-.9 0-1.7.7-1.7 1.7v11.6h-43.3v-11.6c0-.9-.7-1.7-1.7-1.7s-1.7.7-1.7 1.7v13.2c0 .9.7 1.7 1.7 1.7h46.7c.9 0 1.7-.7 1.7-1.7v-13.2c0-1-.7-1.7-1.7-1.7zm-24.5 6.1c.3.3.8.5 1.2.5.4 0 .9-.2 1.2-.5l10-11.6c.7-.7.7-1.7 0-2.4s-1.7-.7-2.4 0l-7.1 8.3v-25.3c0-.9-.7-1.7-1.7-1.7s-1.7.7-1.7 1.7v25.3l-7.1-8.3c-.7-.7-1.7-.7-2.4 0s-.7 1.7 0 2.4l10 11.6z" />
    </svg>
    <div fxLayout="row" fxLayoutAlign="center center">
      <input id="file" type="file" accept="image/*" (change)="onSelectFile($event.target.files)">
      <label for="file"><strong>Choose a file</strong><span class="dragndrop"> or drag it here</span>.</label>
    </div>
  </div>

零件

onSelectFile(files: FileList) {
    uploadFiles = [];
    if (files.length === 0) {
      return;
    }

    for (var i = 0; i < files.length; i++) {
      this.uploadFiles.push(files[i]);
    }
  }

onsubmit(){
    this.photoService.uploadImage(this.uploadFiles).subscribe()
}

服务

uploadImage(photos: any): Observable<any> {
    const headers = new HttpHeaders({ 'enctype': 'multipart/form-data' });
    const formData = new FormData();
    for (let index = 0; index < photos.images.length; index++) {
      formData.append('images', photos.images[index], photos.images[index].name);
    }
    return this.http.post(`http://localhost:8080/api/v1/image`, formData, { headers: headers });
  }

从浏览器请求

POST /api/v1/image HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Content-Length: 114826
Accept: application/json, text/plain, */*
Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IkExNDRGRkFGN0I5Q0NFQjk4MzY4QTBEMjI0MkMwOEI4IiwidHlwIjoiYXQrand0In0.eyJuYmYiOjE2Mjc3OTc5MjMsImV4cCI6MTYyNzc5ODEyMywiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NTAwMSIsImNsaWVudF9pZCI6IkZldGVfQmlyZF9VSSIsInN1YiI6IjY1OTIwMWUwLTY5NjYtNDllNS1hMTQ1LTI4ZmI4OGEyOTNlMCIsImF1dGhfdGltZSI6MTYyNzc5NzczMywiaWRwIjoibG9jYWwiLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjY1OTIwMWUwLTY5NjYtNDllNS1hMTQ1LTI4ZmI4OGEyOTNlMCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJhZG1pbkBsb2NhbC5jb20iLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9lbWFpbGFkZHJlc3MiOiJhZG1pbkBsb2NhbC5jb20iLCJBc3BOZXQuSWRlbnRpdHkuU2VjdXJpdHlTdGFtcCI6IjMzM2ZjMTU1LWFjOGYtNGNhZS1iMTAzLWE5M2UxMzk3ZWFjZSIsIklkZW50aXR5U2VydmVyIjpbIlJlYWQiLCJDcmVhdGUiLCJVcGRhdGUiLCJEZWxldGUiXSwianRpIjoiMTY0QUM0ODcyQ0M0Q0Y4MURGQjAwN0Y3NEZBQjZBODUiLCJzaWQiOiI2REVEMTIzODkxQzQzNUUwMDkwNTk5REQwRUI3QzYyNyIsImlhdCI6MTYyNzc5NzkyMywic2NvcGUiOlsib3BlbmlkIiwicHJvZmlsZSIsImVtYWlsIl0sImFtciI6WyJwd2QiXX0.MscnzuksdVyThuYMwGUMGUtr32I1Y_ko9TW0LeKr3qgB-YUYJ_GXiJ2KtZCx_BLrR_xzoEAzFVzGmLlwbr7-QLFz6hZ48UuBdwwnYmQFWoIJRderyD9tj_uPZn0FBdiAc7mboYHZaswb19w7ZRBcM9DadTOP91Iy0S_aT9cDVKRpGe5bhcwdFirMzt-Wn3wYWKwTw6ZrAya9O-i6K1ue2ID1SlsFYVKniZwpKmv4PRzlbK6SHqwJOLgA5qOsxJqo_amKRHgqOV9OTvIfole46zJTa3xkz9lhojqoE5xDVLM6bD5m7wH43N0yp76jxC7IPL3MMjhIb_7rLuKpjoFw-A
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.115 Safari/537.36
Content-Type: application/json
Sec-GPC: 1
Origin: http://localhost:4200
Sec-Fetch-Site: same-site
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://localhost:4200/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8

请求有效载荷

------WebKitFormBoundaryAFf7zQ0AfQKOxvQ5
Content-Disposition: form-data; name="images"; filename="Untitled-1.png"
Content-Type: image/png


------WebKitFormBoundaryAFf7zQ0AfQKOxvQ5
Content-Disposition: form-data; name="images"; filename="logopinktransparent.png"
Content-Type: image/png


------WebKitFormBoundaryAFf7zQ0AfQKOxvQ5--

有效的邮递员请求

curl --location --request POST 'http://localhost:8080/api/v1/image' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IkExNDRGRkFGN0I5Q0NFQjk4MzY4QTBEMjI0MkMwOEI4IiwidHlwIjoiYXQrand0In0.eyJuYmYiOjE2Mjc3Mzc3MDcsImV4cCI6MTYyNzczNzkwNywiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NTAwMSIsImNsaWVudF9pZCI6IkZldGVfQmlyZF9VSSIsInN1YiI6IjY1OTIwMWUwLTY5NjYtNDllNS1hMTQ1LTI4ZmI4OGEyOTNlMCIsImF1dGhfdGltZSI6MTYyNzczNzcwMywiaWRwIjoibG9jYWwiLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjY1OTIwMWUwLTY5NjYtNDllNS1hMTQ1LTI4ZmI4OGEyOTNlMCIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL25hbWUiOiJhZG1pbkBsb2NhbC5jb20iLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9lbWFpbGFkZHJlc3MiOiJhZG1pbkBsb2NhbC5jb20iLCJBc3BOZXQuSWRlbnRpdHkuU2VjdXJpdHlTdGFtcCI6IjMzM2ZjMTU1LWFjOGYtNGNhZS1iMTAzLWE5M2UxMzk3ZWFjZSIsIklkZW50aXR5U2VydmVyIjpbIlJlYWQiLCJDcmVhdGUiLCJVcGRhdGUiLCJEZWxldGUiXSwianRpIjoiOTk1OEU3REFEQjBBNEUzN0MyMkU4Q0Q2NUVDNDAyRjUiLCJzaWQiOiJCOTFBM0REMTc4NjVFQ0JFOUI5QzA0NEYwMEMyMTJEQiIsImlhdCI6MTYyNzczNzcwNywic2NvcGUiOlsib3BlbmlkIl0sImFtciI6WyJwd2QiXX0.Ol9Mt93yqOS15UUG2vIGZ58o5iEI7-r4G775BhH7BVudBJvI8haio22mNu_OkLOg5jTPiW_muZdcdpeSbdFIWEB1JhlH51y97AJVPpJs0yVAPOGCF7qIVVQP8JvrOGOl-vQziib1RJSzmVCmFUz96lcCfqjg5-NQlrqKZbacWTd30e7f6Q3Ruh0E9mL3wHm7ZosrST9s0qLG_av48apoOB_7FjNuz_ZGNmr4Tpxxaa2L_R1zbc6U5zRP5jYQ4J-kGPDJnHrFpa-JVrqon2k3zmJhfsxXO43BjokBYvfpnN3u5odHaY73eyLTJi_TvykM0N5RegUZ-gLaIiF5-AbKtQ' \
--form 'images=@"/Users/macbook/Desktop/Untitled-1.png"'

标签: javascriptjavaangularfile-uploadmicronaut

解决方案


我在你的角度代码中注意到这个标题“enctype”。 但是 enctype 不是 http 标准头,你应该使用 Content-Type: multipart/form-data; 给你的标题


推荐阅读