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

时间:2016-02-10 20:34:42

标签: javascript http-post react-native fetch-api

我有一些参数需要POST格式化编码到我的服务器:

$(function(){
//Obtenemos la información de csfrtoken que se almacena por cookies en el cliente
var csrftoken = getCookie('csrftoken');

//Agregamos en la configuración de la funcion $.ajax de Jquery lo siguiente:
$.ajaxSetup({
                beforeSend: function(xhr, settings) {
                    if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) {
                        // Send the token to same-origin, relative URLs only.
                        // Send the token only if the method warrants CSRF protection
                        // Using the CSRFToken value acquired earlier
                        xhr.setRequestHeader("X-CSRFToken", csrftoken);
                    }
                }
});

function sameOrigin(url) {
// test that a given url is a same-origin URL
// url could be relative or scheme relative or absolute

var host = document.location.host; // host + port
var protocol = document.location.protocol;
var sr_origin = '//' + host;
var origin = protocol + sr_origin;
// Allow absolute or scheme relative URLs to same origin
return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
    (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||

!(/^(\/\/|http:|https:).*/.test(url));

}

function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
    var cookies = document.cookie.split(';');
    for (var i = 0; i < cookies.length; i++) {
        var cookie = jQuery.trim(cookies[i]);
        // Does this cookie string begin with the name we want?
        if (cookie.substring(0, name.length + 1) == (name + '=')) {
            cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
            break;
        }
    }
}
return cookieValue;

}


function csrfSafeMethod(method) {
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

});

我正在发送我的请求(目前没有参数),如此

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

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

15 个答案:

答案 0 :(得分:164)

你必须自己整理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 Standard states,如果bodyURLSearchParams对象,则应将其序列化为application/x-www-form-urlencoded。但是,您无法在React Native中执行此操作,因为React Native does not implement URLSearchParams

答案 1 :(得分:19)

使用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');

答案 2 :(得分:5)

做到这一点,而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;
};

答案 3 :(得分:3)

更简单:

.content img {
  max-width: 100%;
}

答案 4 :(得分:3)

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

fetch('https://example.com/login', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  },
  body: new URLSearchParams({
    'param': 'Some value',
    'another_param': 'Another value'
  })
})
  .then(res => {
    // Do stuff with the result
  });

是的,您可以使用Axios或任何您想使用的东西来代替fetch

P.S。 IE不支持URLSearchParams

答案 5 :(得分:2)

只需使用

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

答案 6 :(得分:2)

answer

它对我很有帮助,并且可以正常工作

引用:https://gist.github.com/milon87/f391e54e64e32e1626235d4dc4d16dc8

答案 7 :(得分:1)

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

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

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

使用表单编码功能代替JSON.stringify

重新更新:

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

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

不要创建额外的对象。只需将您的值分配给body即可。

答案 8 :(得分:1)

如果您使用的是JQuery,它也可以使用。.

StateService

答案 9 :(得分:1)

fetch 包裹在一个简单的函数中

async function post_www_url_encdoded(url, data) {
    const body = new URLSearchParams();
    for (let key in data) {
        body.append(key, data[key]);
    }
    return await fetch(url, { method: "POST", body });
}

const response = await post_www_url_encdoded("https://example.com/login", {
    "name":"ali",
    "password": "1234"});
if (response.ok){ console.log("posted!"); }

答案 10 :(得分:0)

根据the spec,使用encodeURIComponent不会为您提供一致的查询字符串。它指出:

  
      
  1. 控件名称和值被转义。 空格字符替换为+ ,然后按[RFC1738]第2.2节中的描述转义保留的字符:非字母数字字符替换为%HH(百分号)和两个十六进制数字代表该字符的ASCII码。换行符表示为“ CR LF”对(即%0D%0A)。
  2.   
  3. 控件名称/值以它们在文档中出现的顺序列出。名称与值之间用=隔开,名称/值对之间由&隔开。
  4.   

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

表单主体应使用其他答案中所示的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"

答案 11 :(得分:0)

*/ 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))
    })

使用 npm我querystring --save 后,它可以正常工作。

答案 12 :(得分:0)

您可以使用react-native-easy-app,它更容易发送http请求和制定拦截请求。

import { XHttp } from 'react-native-easy-app';

* Synchronous request
const params = {name:'rufeng',age:20}
const response = await XHttp().url(url).param(params).formEncoded().execute('GET');
const {success, json, message, status} = response;


* Asynchronous requests
XHttp().url(url).param(params).formEncoded().get((success, json, message, status)=>{
    if (success){
       this.setState({content: JSON.stringify(json)});
    } else {
       showToast(msg);
    }
});

答案 13 :(得分:0)

只需将主体设置为以下

var reqBody = "username="+username+"&password="+password+"&grant_type=password";

然后

fetch('url', {
      method: 'POST',
      headers: {
          //'Authorization': 'Bearer token',
          'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
      },
      body: reqBody
  }).then((response) => response.json())
      .then((responseData) => {
          console.log(JSON.stringify(responseData));
      }).catch(err=>{console.log(err)})

答案 14 :(得分:-18)

要上传表单编码的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);