Onjuiste vraag gesteld, zie mijn update hieronder
Ik moet mijn AngularJS-project integreren met een bestaande RESTful API. Deze API verbruikt POST-verzoeken die upload a file
en dienen ook de formuliergegevens in een verzoek in. Helaas moet een van de formulierinvoer in Content-Type: Application/json
zijn.
Na zoeken op internet kon ik alleen POST
met Content-Type: multipart/form-data
waarin geen van de onderdelen een specifieke MIME
.
Hoe kan ik mijn multipart/form-data
samenstellen met een andere MIME
voor elk onderdeel 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--
Relevante referenties:
- https://developer.mozilla.org/en-US/ docs/Web/Guide/Using_FormData_Objects
- REST – HTTP Post Multipart met JSON
- http://code.activestate .com/recipes/578846-composing-a-postable-http-request-with-multipartfo/
- application/x-www-form-urlencoded of multipart /form-data?
- https://stackoverflow.com/a/9082243/764592
Bijwerken
Excuses voor het stellen van een verkeerde vraag. Het oorspronkelijke probleem is dat ik de server de logica kan zien roepen zoiets als,
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
Ik ben er ook in geslaagd om erachter te komen hoe ik zo’n postverzoek kan indienen. Ik zal mijn antwoord hieronder plaatsen.
Nogmaals sorry voor het stellen van een verkeerde vraag.
Antwoord 1, autoriteit 100%
Volgens de documentatie van FormData
, kunt u een veld met een specifiek inhoudstype toevoegen met behulp van de Blob
-constructor:
var formData = new FormData();
formData.append('items', new Blob([JSON.stringify({
name: "Book",
quantity: "12"
})], {
type: "application/json"
}));
Na zorgvuldige observatie blijkt dat het het onderdeel als volgt zal verzenden:
Content-Disposition: form-data; name="items"; filename="blob"
Content-Type: text/json
Het enige alternatief, veilig om het hele verzoek zelf te bouwen, is om een stringwaarde door te geven:
formData.append('items', '{"name": "Book", "quantity": "12"}');
Hierdoor wordt helaas de Content-Type
header niet ingesteld.
Antwoord 2, autoriteit 8%
Fout #1: Ik neem ten onrechte aan dat de itemseen json moeten zijn, zodat we het attribuut kunnen noemen.
Oplossing: het is heel eenvoudig om een meerdelige aanvraag in te dienen die een bestand en een objectachtig formaat bevat.
form = new FormData();
form.append('items[name]', 'Book');
form.append('items[quantity]', 12);
form.append('image', imageFile);
form.append('owner', 'John Doe');
Dus dus zullen de header en body van het verzoek er ongeveer zo uitzien
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--
Antwoord 3, autoriteit 3%
Niets zou dit laten werken, totdat ik de Content-Type
header op undefined zette. In mijn geval plaats ik een bestand en wat 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;
}