Comporre multipart / form-data con un Content-Type diverso su ogni parte con Javascript (o Angular)

Domanda errata, vedi il mio aggiornamento qui sotto

Devo integrare il mio progetto AngularJS con un’API RESTful esistente. Queste API utilizzano la richiesta POST che upload a file e inviano i dati del modulo in una richiesta. Sfortunatamente, uno degli input del modulo deve essere Content-Type: Application/json in Content-Type: Application/json .

Dopo la ricerca sul Web, ho potuto pubblicare solo POST con Content-Type: multipart/form-data in cui ciascuna delle parti non ha un MIME specifico. Come posso comporre il mio multipart/form-data con un MIME diverso per ogni parte in Javascript?

 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-- 

Riferimenti rilevanti:

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

Aggiornare

Chiedere scusa per aver fatto una domanda sbagliata. Il problema originale è che, posso vedere il server che chiama la logica qualcosa del genere,

 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 

Sono anche riuscito a capire come inviare una richiesta di questo tipo. Pubblicherò la mia risposta qui sotto.

Ancora una volta mi dispiace per aver fatto una domanda sbagliata.

In base alla documentazione di FormData , è ansible aggiungere un campo con un tipo di contenuto specifico utilizzando il costruttore Blob :

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

Dopo un’attenta osservazione, si scopre che invierà la parte come segue:

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

L’unica alternativa, sicura di build da sola l’intera richiesta è di passare un valore stringa:

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

Questo, sfortunatamente, non imposta l’intestazione Content-Type .

Errore n. 1: presumo erroneamente che gli articoli debbano essere un json, in modo che possiamo chiamare il suo attributo.

Soluzione: inviare una richiesta multipart contenente un file e un object come il formato è molto semplice.

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

Pertanto, l’intestazione e il corpo della richiesta saranno simili a questo

 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--