我有一些参数,我想POST表单编码到我的服务器:

{
    '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
  }); 

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


当前回答

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('http://identity.azurewebsites.net' + '/token', {
  method: 'POST',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/x-www-form-urlencoded'
  },
  body: formBody
})

它对我很有帮助,而且没有任何错误

参考资料:https://gist.github.com/milon87/f391e54e64e32e1626235d4dc4d16dc8

其他回答

只是这样做,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', 'XXXX-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;
};

在最初的示例中,您有一个transformRequest函数,它将对象转换为Form Encoded数据。

在修改后的示例中,您已将其替换为JSON。stringify将对象转换为JSON。

在这两种情况下,你都有'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',所以在这两种情况下,您都声称要发送表单编码的数据。

使用你的表单编码函数,而不是JSON.stringify。


重新更新:

在第一个获取示例中,将主体设置为JSON值。

现在您已经创建了一个Form Encoded版本,但是您没有将主体设置为该值,而是创建了一个新对象,并将Form Encoded数据设置为该对象的属性。

不要创建额外的对象。把你的值赋给身体。

你可以使用UrlSearchParams,然后像这样做一个toString():

这里有一个简单的方法:

fetch('https://example.com/login', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
    },
    body: new UrlSearchParams(...{
        'userName': 'test@gmail.com',
        'password': 'Password!',
        'grant_type': 'password'
    })
    .toString()
})
.then(res => {
    //Deal with response:
})

对于上传表单编码的POST请求,我建议使用FormData对象。

示例代码:

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

var formData = new FormData();

for (var k in params) {
    formData.append(k, params[k]);
}

var request = {
    method: 'POST',
    headers: headers,
    body: formData
};

fetch(url, request);

更简单:

fetch('https://example.com/login', {
    method: 'POST',
    headers:{
      'Content-Type': 'application/x-www-form-urlencoded'
    },    
    body: new URLSearchParams({
        'userName': 'test@gmail.com',
        'password': 'Password!',
        'grant_type': 'password'
    })
});

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