web-dev-qa-db-ja.com

Javascript(またはAngular)を使用して、各パートで異なるContent-Typeのマルチパート/フォームデータを構成します

間違った質問がありました、以下の私の更新を参照してください

AngularJSプロジェクトを既存のRESTful APIと統合する必要があります。これらのAPIはPOST request upload a file、およびリクエストでフォームデータを送信します。残念ながら、フォーム入力の1つはContent-Type: Application/json

Webで検索した後、POSTのみがContent-Type: multipart/form-data各部分には特定のMIMEがありません。 multipart/form-data Javascriptの各部分に異なるMIMEがありますか?

POST /api/v1/inventory
Host: localhost:8000
Origin: http://localhost:9000
Content-Type: multipart/form-data; boundary=------border

------border
Content-Disposition: form-data; name="owner"

john doe
------border
Content-Disposition: form-data; name="image"; filename="mybook.png"
Content-Type: image/png


------border
Content-Disposition: form-data; name="items"
Content-Type: application/json

{"name": "Book", "quantity": "12"}
------border--

関連資料:

  1. https://developer.mozilla.org/en-US/docs/Web/Guide/Using_FormData_Objects
  2. REST-JSONを使用したHTTP Post Multipart
  3. http://code.activestate.com/recipes/578846-composing-a-postable-http-request-with-multipartfo/
  4. application/x-www-form-urlencodedまたはmultipart/form-data?
  5. https://stackoverflow.com/a/9082243/764592

更新

間違った質問をしたことをおpoびします。元の問題は、サーバーが次のようなロジックを呼び出すことを確認できることです。

func POST(req):
     owner = req.owner // This is string
     image = req.image // This is file object
     itemQuantity = req.items.quantity // Items is an object with attribute quantity
     itemName = req.items.name // Items is an object with attribute name

また、このような投稿リクエストを送信する方法を見つけました。以下に回答を掲載します。

間違った質問をして申し訳ありません。

31
Yeo

FormData のドキュメントによれば、 Blob コンストラクタを使用して、特定のコンテンツタイプのフィールドを追加できます。

var formData = new FormData();

formData.append('items', new Blob([JSON.stringify({
    name: "Book",
    quantity: "12"
})], {
    type: "application/json"
}));

注意深く観察した結果、次のようにパーツが送信されることがわかりました。

Content-Disposition: form-data; name="items"; filename="blob"
Content-Type: text/json

リクエスト全体を自分で作成しない安全な唯一の方法は、文字列値を渡すことです。

formData.append('items', '{"name": "Book", "quantity": "12"}');

残念ながら、これはContent-Typeヘッダーを設定しません。

56
Ja͢ck

間違い#1:itemsはjsonである必要があると誤って仮定しているため、その属性を呼び出すことができます。

解決策:ファイルと形式のようなオブジェクトを含むマルチパートリクエストを送信するのは非常に簡単です。

form = new FormData();
form.append('items[name]', 'Book');
form.append('items[quantity]', 12);
form.append('image', imageFile);
form.append('owner', 'John Doe');

したがって、リクエストのヘッダーと本文は次のようになります

POST /api/v1/inventory
Host: localhost:8000
Origin: http://localhost:9000
Content-Type: multipart/form-data; boundary=------border

------border
Content-Disposition: form-data; name="owner"

john doe
------border
Content-Disposition: form-data; name="image"; filename="mybook.png"
Content-Type: image/png


------border
Content-Disposition: form-data; name="items[name]"

Book
------border
Content-Disposition: form-data; name="items[quantity]"

12
------border--
6
Yeo

Content-Typeヘッダーを未定義に設定するまで、これが機能することはありません。私の場合、ファイルとjsonを投稿しています。

public uploadFile(code: string, file):angular.IHttpPromise<any>{
    var data = `{"query":"mutation FIRMSCORECARD_CALCULATE($code:String!){ FirmScorecardMutation{ BatchCalculate(Code:$code) }}","variables":{"code":"${code}"},"operationName":"FIRMSCORECARD_CALCULATE"}`;
    var formData = new FormData();
    formData.append('operations', data);
    formData.append('file', file, file.name);

    let config = {
        headers: {
            'Accept': 'application/json',
            'Content-Type': undefined
        }
    };
    let response = this.$http.post(this.graphqlUrl, formData, config);
    return response;
}
0
N-ate