Javascript 发布来自 React Native 的 x-www-form-urlencoded 请求

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35325370/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 17:35:38  来源:igfitidea点击:

Post a x-www-form-urlencoded request from React Native

javascripthttp-postreact-nativefetch-api

提问by texas697

I have some parameters that I want to POST form-encoded to my server:

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

{
    'userName': '[email protected]',
    'password': 'Password!',
    'grant_type': 'password'
}

I'm sending my request (currently without parameters) like this

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

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

How can I include the form-encoded parameters in the request?

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

采纳答案by David Kay

For uploading Form-Encoded POST requests, I recommend using the FormDataobject.

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

Example code:

示例代码:

var params = {
    userName: '[email protected]',
    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);

回答by Narongdej Sarnsuwan

You have to put together the x-www-form-urlencoded payload yourself, like this:

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

var details = {
    'userName': '[email protected]',
    '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
})

Note that ifyou were using fetchin a (sufficiently modern) browser, instead of React Native, you could instead create a URLSearchParamsobject and use that as the body, since the Fetch Standard statesthat if the bodyis a URLSearchParamsobject then it should be serialised as application/x-www-form-urlencoded. However, you can't do this in React Native because React Native does not implement URLSearchParams.

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

回答by Nicu Criste

Use URLSearchParams

URLSearchParams

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

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

var data = new URLSearchParams();
data.append('userName', '[email protected]');
data.append('password', 'Password');
data.append('grant_type', 'password');

回答by alex_1948511

Even more simpler:

更简单:

body: new URLSearchParams({
      'userName': '[email protected]',
      'password': 'Password!',
      'grant_type': 'password'
    }),

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

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

回答by P-A

Just did this and UrlSearchParams did the trick Here is my code if it helps someone

刚刚做了这个,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;
};

回答by Akshita Agarwal

*/ import this statement */
import qs from 'querystring'

fetch("*your url*", {
            method: 'POST',
            headers: {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'},
            body: qs.stringify({ 
                username: "akshita",
                password: "123456",
            })
    }).then((response) => response.json())
      .then((responseData) => {
         alert(JSON.stringify(responseData))
    })

After using npm i querystring --saveit's work fine.

使用npm i querystring --save 后,它工作正常。

回答by mojTaba Shayegh

Just Use

就用

import  qs from "qs";
 let data = {
        'profileId': this.props.screenProps[0],
        'accountId': this.props.screenProps[1],
        'accessToken': this.props.screenProps[2],
        'itemId': this.itemId
    };
    return axios.post(METHOD_WALL_GET, qs.stringify(data))

回答by mahsa k

var details = {
    'userName': '[email protected]',
    '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
})

it is so helpful for me and works without any error

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

refrence : https://gist.github.com/milon87/f391e54e64e32e1626235d4dc4d16dc8

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

回答by wishy

If you are using JQuery, this works too..

如果您使用的是 JQuery,这也适用..

fetch(url, {
      method: 'POST', 
      body: $.param(data),
      headers:{
        'Content-Type': 'application/x-www-form-urlencoded'
      }
})

回答by Quentin

In the original example you have a transformRequestfunction which converts an object to Form Encoded data.

在原始示例中,您有一个transformRequest将对象转换为表单编码数据的函数。

In the revised example you have replaced that with JSON.stringifywhich converts an object to JSON.

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

In both cases you have 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'so you are claimingto be sending Form Encoded data in both cases.

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

Use your Form Encoding function instead of JSON.stringify.

使用您的表单编码功能而不是JSON.stringify.



Re update:

重新更新:

In your first fetchexample, you set the bodyto be the JSON value.

在您的第一个fetch示例中,您将 设置body为 JSON 值。

Now you have created a Form Encoded version, but instead of setting the bodyto be that value, you have created a new object and set the Form Encoded data as a property of that object.

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

Don't create that extra object. Just assign your value to body.

不要创建那个额外的对象。只需将您的值分配给body.

回答by papiro

According to the spec, using encodeURIComponentwon't give you a conforming query string. It states:

根据规范, usingencodeURIComponent不会为您提供符合要求的查询字符串。它指出:

  1. Control names and values are escaped. Space characters are replaced by +, and then reserved characters are escaped as described in [RFC1738], section 2.2: Non-alphanumeric characters are replaced by %HH, a percent sign and two hexadecimal digits representing the ASCII code of the character. Line breaks are represented as "CR LF" pairs (i.e., %0D%0A).
  2. The control names/values are listed in the order they appear in the document. The name is separated from the value by =and name/value pairs are separated from each other by &.
  1. 控件名称和值被转义。空格字符被替换为+,然后保留字符被转义,如 [RFC1738] 第 2.2 节所述:非字母数字字符被替换为%HH、一个百分号和两个表示字符 ASCII 代码的十六进制数字。换行符表示为“CR LF”对(即,%0D%0A)。
  2. 控件名称/值按它们在文档中出现的顺序列出。名称与值之间由 分隔=,名称/值对之间由 分隔&

The problem is, encodeURIComponentencodes spaces to be %20, not +.

问题是,encodeURIComponent将空格编码为%20,而不是+

The form-body should be coded using a variation of the encodeURIComponentmethods shown in the other answers.

应使用encodeURIComponent其他答案中显示的方法的变体对表单主体进行编码。

const formUrlEncode = str => {
  return str.replace(/[^\d\w]/g, char => {
    return char === " " 
      ? "+" 
      : encodeURIComponent(char);
  })
}

const data = {foo: "bar???˙∑  baz", boom: "pow"};

const dataPairs = Object.keys(data).map( key => {
  const val = data[key];
  return (formUrlEncode(key) + "=" + formUrlEncode(val));
}).join("&");

// dataPairs is "foo=bar%C3%9F%C6%92%C2%A9%CB%99%E2%88%91++baz&boom=pow"