Подтвердить что ты не робот

Составление многочастных/форм-данных с другим типом контента на каждой части с Javascript (или Angular)

Неверный вопрос, см. мое обновление ниже

Мне нужно интегрировать мой проект AngularJS с существующим API RESTful. Эти API используют запрос POST, который upload a file, а также передает данные формы в запрос. К сожалению, один из входных данных формы должен находиться в Content-Type: Application/json.

После поиска в Интернете я мог только POST с Content-Type: multipart/form-data, в котором каждая из частей не имеет определенного MIME. Как я могу составить свой multipart/form-data с другим MIME для каждой части в 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--

Соответствующие ссылки:


Update

Извиниться за неправильный вопрос. Первоначальная проблема заключается в том, что я вижу, как сервер вызывает логику, например,

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

Мне также удалось выяснить, как отправить такой почтовый запрос. Я отправлю свой ответ ниже.

Еще раз жаль, что задал неправильный вопрос.

4b9b3361

Ответ 1

В соответствии с документацией FormData вы можете добавить поле с определенным типом контента с помощью Blob constructor:

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.

Ответ 2

Ошибка №1: Я ошибочно полагаю, что элементы должны быть 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--

Ответ 3

Ничто не заставит это работать, пока я не установлю заголовок Content-Type на undefined. В моем случае я публикую файл и некоторые 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;
}