如何使用 Fetch 发布 x-www-form-urlencoded 请求?

IT技术 javascript http-post fetch-api
2021-01-29 03:49:46

我有一些参数要通过表单编码发送到我的服务器:

{
    'userName': 'test@gmail.com',
    'password': 'Password!',
    'grant_type': 'password'
}

我像这样发送我的请求(目前没有参数)

var obj = {
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
  },
};
fetch('https://example.com/login', obj)
  .then(function(res) {
    // Do stuff with result
  }); 

如何在请求中包含表单编码参数?

6个回答

您必须自己将 x-www-form-urlencoded 有效载荷放在一起,如下所示:

var details = {
    'userName': 'test@gmail.com',
    'password': 'Password!',
    'grant_type': 'password'
};

var formBody = [];
for (var property in details) {
  var encodedKey = encodeURIComponent(property);
  var encodedValue = encodeURIComponent(details[property]);
  formBody.push(encodedKey + "=" + encodedValue);
}
formBody = formBody.join("&");

fetch('https://example.com/login', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
  },
  body: formBody
})

请注意,如果fetch在(足够现代的)浏览器中使用,而不是 React Native,您可以创建一个URLSearchParams对象并将其用作主体,因为Fetch 标准指出,如果body是一个URLSearchParams对象,那么它应该被序列化为application/x-www-form-urlencoded. 但是,您不能在 React Native 中执行此操作,因为 React Native没有实现URLSearchParams.

它将json数组参数转换为字符串
2021-03-13 03:49:46
URLSearchParams github.com/WebReflection/url-search-params 的这个polyfill可能适用于 React Native 或更旧的浏览器。
2021-03-19 03:49:46
我已经尝试了所有建议的方法。无论我做什么,fetch 都会在正文周围注入不需要的引号,直接插入字符串 - 开始和结束引号。这会导致参数被解析,例如像这样:'"mykey': 'myvalue"'。这使得调用 API 变得不可能,因为这些当然只会导致 400 个错误(服务器识别 mykey,而不是“mykey”)。其他人有这个问题吗?莫名其妙。
2021-03-19 03:49:46
另一种类似的方式: const formBody = Object.entries(details).map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value)).join('&')
2021-04-03 03:49:46
ES6方式: const formBody = Object.keys(details).map(key => encodeURIComponent(key) + '=' + encodeURIComponent(details[key])).join('&');
2021-04-11 03:49:46

更简单:

fetch('https://example.com/login', {
    method: 'POST',
    body: new URLSearchParams({
        'userName': 'test@gmail.com',
        'password': 'Password!',
        'grant_type': 'password'
    })
});

文档:https : //developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch

利用 URLSearchParams

https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams

var data = new URLSearchParams();
data.append('userName', 'test@gmail.com');
data.append('password', 'Password');
data.append('grant_type', 'password');
它现在是 React Native 的一部分。toString()在传递数据 request 之前一定要调用body
2021-03-13 03:49:46
即使在 RN 说他们实施了之后URLSearchParams,我仍然有问题。我不认为它是按照规范实施的,它不仅仅是解决方案的下降。如果您尝试加入但仍有问题,请考虑阅读URLSearchParams '错误:未实施'URLSearchParams
2021-04-07 03:49:46

刚刚做了这个,UrlSearchParams 做了这个伎俩这是我的代码,如果它对某人有帮助的话

import 'url-search-params-polyfill';
const userLogsInOptions = (username, password) => {



// const formData = new FormData();
  const formData = new URLSearchParams();
  formData.append('grant_type', 'password');
  formData.append('client_id', 'entrance-app');
  formData.append('username', username);
  formData.append('password', password);
  return (
    {
      method: 'POST',
      headers: {
        // "Content-Type": "application/json; charset=utf-8",
        "Content-Type": "application/x-www-form-urlencoded",
    },
      body: formData.toString(),
    json: true,
  }
  );
};


const getUserUnlockToken = async (username, password) => {
  const userLoginUri = `${scheme}://${host}/auth/realms/${realm}/protocol/openid-connect/token`;
  const response = await fetch(
    userLoginUri,
    userLogsInOptions(username, password),
  );
  const responseJson = await response.json();
  console.log('acces_token ', responseJson.access_token);
  if (responseJson.error) {
    console.error('error ', responseJson.error);
  }
  console.log('json ', responseJson);
  return responseJson.access_token;
};

无需使用 jQuery,querystring无需手动组装有效负载。URLSearchParams是一种方法,这里是完整请求示例中最简洁的答案之一:

fetch('https://example.com/login', {
  method: 'POST',
  body: new URLSearchParams({
    param: 'Some value',
    anotherParam: 'Another value'
  })
})
  .then(response => {
    // Do stuff with the response
  });

使用async/的相同技术await

const login = async () => {
  const response = await fetch('https://example.com/login', {
    method: 'POST',
    body: new URLSearchParams({
      param: 'Some value',
      anotherParam: 'Another value'
    })
  })

  // Do stuff with the response
}

是的,您可以使用 Axios 或任何其他 HTTP 客户端库而不是 native fetch