POST API Javascript из файла JSON с fs readFile и картой

Здесь с javascript мы делаем API POST, используя внешний файл JSON. Затем у нас есть 2 файла order.json и app.js.

мой сервер: убунту 22.04 узел v19.2.0 нпм 8.19.3

Скрипт получает данные из файла order.js с помощью readFile. app.js

var myHeaders = new Headers();
myHeaders.append("api-key", "123");
myHeaders.append("Content-Type", "text/plain");
myHeaders.append("Cookie", "session_id=123");

// get order.json file
var fs = require('fs')
fs.readFile('order.json', 'utf8', (err, data) => {
    if (err) throw err
    let orders = JSON.parse(data)

    let order_line = orders.map(o => ([0, 0, {
        product_id: +o.product_id,
        product_uom_qty: +o.product_uom_qty,
        price_unit: +o.price_unit
    }]));

    let body = {
        partner_id: 150,
        user_id: 6,
        workflow_id: 1,
        order_line
    }

    let raw = JSON.stringify(body);

    console.info(raw);



    var requestOptions = {
        method: 'POST',
        headers: myHeaders,
        body: raw,
        redirect: 'follow'
    }


    fetch("https://mysite/api/sale.order/create?api_key=123", requestOptions)
        .then(response => response.text())
        .then(result => console.info(result))
        .catch(error => console.info('error', error))

})

файл находится по пути ./ и содержит общий заказ продаж из вашего магазина. заказ.json

[
    {
        "sku": "123",
        "product_id": "6",
        "price_unit": "9.7",
        "product_uom_qty": "1.0000"
    },
    {
        "sku": "456",
        "product_id": "7",
        "price_unit": "9.8",
        "product_uom_qty": "1.0000"
    }
]

Во-первых, вы не должны сами создавать JSON, а использовать что-то вроде JSON.stringify Во-вторых: почему вы отправляете контент-тип text/plain, когда вы явно отправляете данные JSON? Пожалуйста, также опубликуйте соответствующие заголовки, которые отправляет почтальон ... Кроме того, вы проверили, как на самом деле выглядит ваш raw? Я предполагаю, что он содержит что-то вроде [object Object], который является результатом неявного вызова toString(), который происходит, когда вы создаете свою строку raw... Это (вероятно, вместе с плохо написанным сервером), вероятно, приводит к ошибке при разборе вашего тела запроса...

derpirscher 12.01.2023 14:30

Я добавил полную выборку почтальона. Я проверяю JSON.stringify

Jhon Scott 12.01.2023 14:59
Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
0
2
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Не создавайте JSON самостоятельно, а используйте существующий хорошо работающий метод сериализации (например, встроенный JSON.stringify)

let orders = [
  {
    sku: 123,
    product_id: 6,
    price_unit: 9.7,
    product_uom_qty: 1.0,
  },
  {
    sku: 456,
    product_id: 7,
    price_unit: 9.8,
    product_uom_qty: 1.0,
  },
];

let order_line = orders.map(o => ([0,0, { 
  product_id: o.product_id,
  product_uom_qty: o.product_uom_qty,
  price_unit: o.price_unit
  }]));

let body = {
  partner_id: 150,
  user_id: 6,
  workflow_id: 1,
  order_line 
}

let raw = JSON.stringify(body);

console.info(raw);

Имейте в виду, что я инициализировал orders из массива, а не читал его с диска, но это не имеет особого значения, если предположить, что orders.json содержит действительные данные JSON. Но я заметил, что типы данных в вашем orders.json отличаются от типов данных в данных, отправленных через почтальона. То есть, например, price_unit — это строка в вашем JSON, но число в ваших опубликованных данных. Вам нужно будет это исправить. Я исправил это в массиве orders в своем фрагменте.

Если вы не можете повлиять на структуру вашего json, вы также можете преобразовать между строкой и числом при создании вашего объекта, как это (обратите внимание на + перед доступом к свойству, который преобразует строку из вашего объекта заказа в число)

let order_line = orders.map(o => ([0,0, { 
  product_id: +o.product_id,
  product_uom_qty: +o.product_uom_qty,
  price_unit: +o.price_unit
}]));

Я также использовал Array.map вместо цикла for...

Это создаст допустимую строку JSON, которую можно будет правильно проанализировать на сервере.

фрагмент работает так хорошо, спасибо. Но заметьте, мне нужно перенести содержимое моего JSON в переменную let ordres, потому что оно экспортируется из другой системы. Я пытаюсь получить содержимое с помощью fs.readFile и выполнить синтаксический анализ. Но не работает. В чем дело?

Jhon Scott 12.01.2023 17:47

Как я уже говорил, ваш JSON содержит строки для некоторых значений (например, product_uom_qty обратите внимание на кавычки ' вокруг значений?), но API, похоже, ожидает числа...

derpirscher 12.01.2023 19:51

работает! вы делаете :) глубоко спасибо за объяснение.

Jhon Scott 13.01.2023 00:50

Другие вопросы по теме