如何使用axios实例将单个值作为请求主体进行POST。

huangapple go评论66阅读模式
英文:

How to POST single value as request body using axios instance

问题

我有一个POST API如下:

  • URL: /get-item
  • 方法:POST
  • 请求体:id(整数)

我知道将单个值作为请求体而不是查询或路径参数有点奇怪,但就是这样。

现在我正在尝试从我的React App中使用以下代码调用API。

export const axiosInstance = axios.create(AXIOS_BASE_CONFIG);
// ...

const loadMyItem = async (itemId) => {
    console.log("itemId:: ", itemId);
    setLoading(true);
    axiosInstance.post(
      URL_GetMyItem,
      itemId
    ).then((res) => {
      console.log("res", res);
      setMyItem(res?.result);
    }).catch((err) => {
      errorHandler(err);
    }).finally(() => {
      setLoading(false)
    })
  }

但是收到了"Bad Request"错误。

响应:

{"timestamp":"...","status":400,"error":"Bad Request","path":"/.../get-item"}

如何使用axios调用一个具有单个值作为请求体的POST API?

英文:

I have an POST API as:

  • URL: /get-item
  • Method: POST
  • Request Body: id(Integer)

I know it's little weird to have a single value as request body instead of query or path parameter but it is what it is.

Now I am trying to call the API from my React App using below code.

export const axiosInstance = axios.create(AXIOS_BASE_CONFIG);
// ...

const loadMyItem = async (itemId) => {
    console.log("itemId:: ", itemId);
    setLoading(true);
    axiosInstance.post(
      URL_GetMyItem,
      itemId
    ).then((res) => {
      console.log("res", res);
      setMyItem(res?.result);
    }).catch((err) => {
      errorHandler(err);
    }).finally(() => {
      setLoading(false)
    })
  }

But getting Bad Request error.

Response:

{"timestamp":"...","status":400,"error":"Bad Request","path":"/.../get-item"}

How to call a POST API having single value as Request Body using axios?

答案1

得分: 1

默认情况下,Axios将检测到您的 itemId 负载是一个基本数据类型(字符串/数字),将其字符串化并以 content-type: application/x-www-form-urlencoded 发送。

问题在于,整数的字符串化版本不是这个标头的有效格式。

您需要自定义 content-type 标头,并将值以 JSON 形式发送

axiosInstance
  .post(URL_GetMyItem, JSON.stringify(itemId), {
    headers: {
      "content-type": "application/json",
    },
  })
  .then(({ data }) => {
    setMyItem(data.result);
  })
  .catch(errorHandler)
  .finally(() => {
    setLoading(false);
  });

我强烈推荐的另一种选择是 Fetch API,它不那么具有偏见,更加稳定

fetch(new URL(URL_GetMyItem, AXIOS_BASE_CONFIG.baseURL), {
  method: "POST",
  headers: {
    "content-type": "application/json",
  },
  body: JSON.stringify(itemId),
})
  .then((response) => {
    if (!response.ok) {
      throw an Error(`请求失败: ${URL_GetMyItem}`);
    }
    return response.json();
  })
  .then((data) => {
    setMyItem(data.result);
  })
  .catch(errorHandler)
  .finally(() => {
    setLoading(false);
  });
英文:

By default, Axios will detect that your itemId payload is a primitive (string / number), stringify it and send it with content-type: application/x-www-form-urlencoded.

The issue there is that the stringified version of an integer is not a valid format for this header.

You will need to customise the content-type header and send the value as JSON

axiosInstance
  .post(URL_GetMyItem, JSON.stringify(itemId), {
    headers: {
      "content-type": "application/json",
    },
  })
  .then(({ data }) => {
    setMyItem(data.result);
  })
  .catch(errorHandler)
  .finally(() => {
    setLoading(false);
  });

An alternative I highly recommend is the Fetch API which isn't so opinionated and more stable

fetch(new URL(URL_GetMyItem, AXIOS_BASE_CONFIG.baseURL), {
  method: "POST",
  headers: {
    "content-type": "application/json",
  },
  body: JSON.stringify(itemId),
})
  .then((response) => {
    if (!response.ok) {
      throw new Error(`Request failed: ${URL_GetMyItem}`);
    }
    return response.json();
  })
  .then((data) => {
    setMyItem(data.result);
  })
  .catch(errorHandler)
  .finally(() => {
    setLoading(false);
  });

huangapple
  • 本文由 发表于 2023年3月1日 11:03:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/75599217.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定