I have some parameters that I want to POST form-encoded to my server:
{
'userName': 'test#gmail.com',
'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?
You have to put together the x-www-form-urlencoded payload yourself, like this:
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
})
Note that if you were using fetch in a (sufficiently modern) browser, instead of React Native, you could instead create a URLSearchParams object and use that as the body, since the Fetch Standard states that if the body is a URLSearchParams object 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.
Even simpler:
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'
})
});
Docs: https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch
Use 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');
Just did this and UrlSearchParams did the trick
Here is my code if it helps someone
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;
};
No need to use jQuery, querystring or manually assemble the payload. URLSearchParams is a way to go and here is one of the most concise answers with the full request example:
fetch('https://example.com/login', {
method: 'POST',
body: new URLSearchParams({
param: 'Some value',
anotherParam: 'Another value'
})
})
.then(response => {
// Do stuff with the response
});
The same technique using 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
}
Yes, you can use Axios or any other HTTP client library instead of native fetch.
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
})
it is so helpful for me and works without any error
refrence : https://gist.github.com/milon87/f391e54e64e32e1626235d4dc4d16dc8
You can use FormData and URLSearchParams to post as application/x-www-form-urlencoded with the example below:
If you have a form:
<form>
<input name="username" type="text" />
<input name="password" type="password" />
<button type="submit">login</button>
</form>
You can add use the JS below to submit the form.
const form = document.querySelector("form");
form.addEventListener("submit", async () => {
const formData = new FormData(form);
try {
await fetch("https://example.com/login", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: new URLSearchParams(formData),
});
} catch (err) {
console.log(err);
}
});
*/ 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 --save it's work fine.
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))
If you are using JQuery, this works too..
fetch(url, {
method: 'POST',
body: $.param(data),
headers:{
'Content-Type': 'application/x-www-form-urlencoded'
}
})
You can use UrlSearchParams and then do a toString() like so:
Here is a simple way of doing it:
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:
})
According to the spec, using encodeURIComponent won't give you a conforming query string. It states:
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).
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 &.
The problem is, encodeURIComponent encodes spaces to be %20, not +.
The form-body should be coded using a variation of the encodeURIComponent methods shown in the other answers.
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"
Just set the body as the following
var reqBody = "username="+username+"&password="+password+"&grant_type=password";
then
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)})
You can use react-native-easy-app that is easier to send http request and formulate interception request.
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);
}
});
In the original example you have a transformRequest function which converts an object to Form Encoded data.
In the revised example you have replaced that with JSON.stringify which converts an object to JSON.
In both cases you have 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' so you are claiming to be sending Form Encoded data in both cases.
Use your Form Encoding function instead of JSON.stringify.
Re update:
In your first fetch example, you set the body to be the JSON value.
Now you have created a Form Encoded version, but instead of setting the body to be that value, you have created a new object and set the Form Encoded data as a property of that object.
Don't create that extra object. Just assign your value to body.
wrapped fetch in a simple function
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!"); }
For uploading Form-Encoded POST requests, I recommend using the FormData object.
Example code:
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);
As I said, I want to convert that POST request with a file to JavaScript. This code sends a JSON request which contains an image file to server.
The Dart function is this (convert this to javascript):
Future postData(User user, VideoGame videoGame, File file) async {
Map data = {
'name': user.name,
'contact': user.contact,
'location': {
'country': user.country,
'state': user.state,
'city': user.city
},
'videoGame': {
'name': videoGame.name,
'type': videoGame.type,
'console': videoGame.console,
}
};
try {
String _url = baseUrl + 'insertData';
var uri = Uri.parse(_url);
var request = http.MultipartRequest('POST', uri)
..headers.addAll({'Content-type': 'multipart/form-data', 'Accept': 'multipart/form-data'})
..fields.addAll({'data': json.encode(data)});
request.files.add(
http.MultipartFile(
'image',
file.readAsBytes().asStream(),
file.lengthSync(),
filename: file.path.split("/").last
),
);
var response = await request.send();
print('Status ${response.statusCode}');
if (response.statusCode == 200) {
final respStr = await response.stream.bytesToString();
print(jsonDecode(respStr));
MyALertKey
.currentState
?.setState((){});
}
} catch (e) {
print("Video Games POST error => ${e.toString()}");
}
}
Because the server written in Python I couldn't see that this file sends to server (request full body).
I have written this in JavaScript but it doesn't work.
const handleSubmit = async (e) => {
e.preventDefault();
var data = new FormData()
var blob = new Blob([JSON.stringify({
name: somevalue,
contact: somevalue,
location: {
country: somevalue,
state: somevalue,
city: somevalue
},
videoGame: {
name: somevalue,
type: somevalue,
console: somevalue,
}
})],{
type: 'application/json'
})
data.append('data',blob)
data.append('image',file_from_input)
try {
const res = await fetch('url',{
method:'POST',
cache: 'default',
mode: 'no-cors',
headers: {
'Content-Type': 'multipart/form-data'
},
body: data
})
let data_ = await res.json()
console.log(data_)
} catch (e) {
console.log(e)
}
console.log(res.status) // will be 400 bad request
}
Please help me. Thanks.
i am using a code from a site where onsubmit the call is made and a call is made
$(":submit").click(async (event) => {
i am not aware of this syntax.
my example using the simple $.ajax call and making a post call to the page
so the above function is like this
$(":submit").click(async (event) => {
event.preventDefault();
let response = await fetch("page.cfm");
const reader = response.body.getReader();
const len = response.headers.get("Content-Length") * 1;
my ajax call is like this
$.ajax({
url: "page.cfm",
cache: false,
data : $('#form').serialize(),
method: "post",
beforeSend: function() {
$('div.results').html('Please wait');
},
success: function(response){
$('div.results').html(response);
}
how can i format the above to my ajax call
Include form data in the body. Make sure that your await fetch is inside async functions.
$('document').ready( async function() {
$("#test_fetch").submit( async function(e) {
e.preventDefault(); // avoid to execute the actual submit of the form.
var form = $(this);
var url = form.attr('action');
let response = await fetch(url,{
method:"post",
body: $(form).serialize()
});
...
});
});
You have to change the request to POST and pass the data.
Then read the data from the response
$(":submit").click(async (event) => {
event.preventDefault();
$('div.results').html('Please wait');
let response = await fetch("page.cfm", {method: 'POST', headers: {'Content-Type': 'application/x-www-form-urlencoded'}, body: $('#form').serialize()});
const html = await response.text();
$('div.results').html(html);
});
I want use my api to send e-mail in some cases,the service (infobip) docs show an example in JS but it don't work in my api with nodejs and expressjs. Can someone help me?
/*----Sending fully featured email----*/
function createFormData(data) {
var formData = new FormData();
for (var key in data) {
formData.append(key, data[key]);
}
return formData;
}
//Dummy File Object
var file = new File([""], "filename");
var data = {
'from': 'Sender Name <from#example.com>',
'to': 'recipient1#example.com',
'subject': 'Test Subject',
'html': '<h1>Html body</h1><p>Rich HTML message body.</p>',
'text': 'Sample Email Body',
'attachment': file,
'intermediateReport': 'true',
'notifyUrl': 'https://www.example.com/email/advanced'
};
var xhr = new XMLHttpRequest();
xhr.withCredentials = false;
xhr.addEventListener('readystatechange', function () {
if (this.readyState === this.DONE) {
console.log(this.responseText);
}
});
xhr.open('POST', 'https://{base_url}.infobip.com/email/1/send', false);
xhr.setRequestHeader('authorization', 'Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==');
xhr.setRequestHeader('accept', 'application/json');
xhr.send(createFormData(data));
You should use https from nodejs.
Here an example code to getting started. For infopib it seems to be so normal Post request.
I tried to create an account on this page, but registration seems to can be completed only over sales. So I couldn't provide a working example...
This is why I can only provide a general example how to make an https POST call, which should be a good starting point to develop your solution:
const https = require('https')
const data = JSON.stringify({
todo: 'Buy the milk'
})
const options = {
hostname: 'yourURL.com',
port: 443,
path: '/todos',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': data.length
}
}
const req = https.request(options, (res) => {
console.log(`statusCode: ${res.statusCode}`)
res.on('data', (d) => {
process.stdout.write(d)
})
})
req.on('error', (error) => {
console.error(error)
})
req.write(data)
req.end()