Escape " in axios - axios

I am making an api call to WuFoo forms
to do a dateCreated filter it needs to look like this (note double quote):
Filter1=DateCreated+Is_greater_than+"2019-11-13 12:00:00"
However, Axios urlencodes it to look like this:
Filter1=DateCreated%2BIs_greater_than%2B%222019-11-13+12:00:00%22'
and WuFoo unfortunately returns incorrect response to that.
I have tried escaping the encoding by using paramSerializer:
const instance = axios.create({
baseURL: 'https://subdomain.wufoo.com/api/v3',
timeout: 1000,
headers: { 'Authorization': 'Basic fjdkalfjkdafldklaskflsdkl' },
paramsSerializer: function(params) { return params }
});
....
instance.get('/forms/form/entries.json',{
params:{
Filter1: qDateFilter
}
})
qDateFilter = DateCreated+Is_greater_than+"2019-11-13 12:00:00"
However I now have the following error:
TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters
at new ClientRequest (_http_client.js:139:13)
at Object.request (https.js:309:10)
at RedirectableRequest._performRequest (/home/node/app/node_modules/follow-redirects/index.js:169:24)
at new RedirectableRequest (/home/node/app/node_modules/follow-redirects/index.js:66:8)
at Object.wrappedProtocol.request (/home/node/app/node_modules/follow-redirects/index.js:307:14)
at dispatchHttpRequest (/home/node/app/node_modules/axios/lib/adapters/http.js:180:25)
at new Promise (<anonymous>)
at httpAdapter (/home/node/app/node_modules/axios/lib/adapters/http.js:20:10)
at dispatchRequest (/home/node/app/node_modules/axios/lib/core/dispatchRequest.js:59:10)
at processTicksAndRejections (internal/process/task_queues.js:93:5) {
code: 'ERR_UNESCAPED_CHARACTERS'
}
Attempts to just use a straight full string as a URL don't work either, it still encodes it.
Using straight " in postman works fine, same with curl.
Any other options?

WuFoo got back to me. It wasn't the " it was actually the encoding of the + sign. I replaced with spaces and it worked.

Related

Calling AxiosRef with method and data as empty object not working

I am working in a Nest TypeScript work where I would like to call a http request using AxiosRefby passing the method.
Means instead of calling as this.httpService.axiosRef.get(url, {headers}) I would like to invoke as this.httpService.axiosRef({method, url, headers}).
And there I am seeing some issue:
Here is my working code snippet:
async request<T = any>(creds: CredentialObj, method: Method, data: any, query?: Record<string, string>): Promise<T> {
const headers = this.getHeaders(creds);
const timeout = +(process.env.HTTP_CALL_TIMEOUT || 10000);
const url: string = `<the URL>`;
return this.httpService
.axiosRef.get(url, { headers })
.then((response: AxiosResponse<T>) => this.handleHttpResponse(response))
.catch((error: AxiosError) => this.handleHttpReject(error));
}
But If I change the axiosRef like this:
console.log(`Method: ${method}`);
console.log(`Data: ${JSON.stringify(data)}`);
return this.httpService
.axiosRef({ method, url, headers, data})
.then((response: AxiosResponse<T>) => this.handleHttpResponse(response))
.catch((error: AxiosError) => this.handleHttpReject(error));
It does not work and gives an error:
Method: get
Data: {}
Error: Request failed with status code 400
at createError (..\node_modules\axios\lib\core\createError.js:16:15)
at settle (...\nest-services\node_modules\axios\lib\core\settle.js:17:12)
at IncomingMessage.handleStreamEnd (C:\Users\pradipm\clients\CloudManager\cm_12\occm\service-infra\nest-services\node_modules\axios\lib\adapters\http.js:260:11)
at IncomingMessage.emit (node:events:525:35)
at endReadableNT (node:internal/streams/readable:1358:12)
at processTicksAndRejections (node:internal/process/task_queues:83:21)
It's just an empty data object.
Actually I want to make it like this way of passing the method name such that I can use it for all REST API verbs as a common util routine. For cases other than get (e.g. post, patch) we need to pass the payload. Hence trying to make a single utility for the same.
My axios version is: "axios": "^0.21.1",

500 error when trying to create page using REST API

I'm currently using Confluence server and I'm currently getting a 500 error when I try to create a new page using the REST API. I am currently using an HTML macro that makes GET & POST requests using the Fetch API. I currently have no issues when making GET requests, only issues with POST requests.
I tried researching the error and saw someone mention that they fixed it by turning off collaborative editing in the space, but in my case that is not an option. Anyone have an idea of what is causing this error?
function createPage() {
let url = "http://exampledomain:8090/confluence/rest/api/content/"
fetch(url, {
method: 'POST',
headers: {
'Authorization': 'Basic USER:PASS',
'Content-Type': 'application/json',
},
data: {
'type': 'page',
'title': "New Page",
'ancestors': [{ 'id': 97059352 }], // parent page id
'space': { 'key': "EXAMPLE_SPACE" },
'body': {
'storage': {
'value': "<h1>New Page!</h1>",
'representation': 'storage',
}
},
}
})
.then(response => console.log(response))
.catch(err => console.log(err.message))
}
I see invalid data structure:
'representation': 'storage', <== extra comma
}
}, <== another extra comma
}
Also double check with your programming language that you can use single quotes (') and that they are correctly transformed into double quotes ("). JSON (Jira REST API) accepts only double quotes for keys and string values.

get token from spotify API using axios, error 404

I`m trying to get the token from the spotify API, I use axios. I use the example given by the API as a guide, but give me the error 404
export const getToken = code => async dispatch => {
const responseToken = await axios.post({
url: "https://accounts.spotify.com/api/token",
form: {
grant_type: "authorization_code",
code,
redirect_uri
},
headers: {
'Authorization': 'Basic ' + (new Buffer(client_id + ':' + client_secret).toString('base64'))
},
json: true
})
console.log(responseToken);
The first line is because I`m using redux,I just wanted you to see that it was a asinc method.
I have being all day trying to fix this, I don`t have more ideas of how to solve this
Try changing
form: {
grant_type: "authorization_code",
code,
redirect_uri
}
to
data: JSON.stringify({
grant_type: "authorization_code",
code,
redirect_uri
})
You want to send it in the request body, hence "data", that's how you define it in axios.
Also, I don't think you need json: true
EDIT:
Pretty sure you have to add 'content-type': 'application/x-www-form-urlencoded;charset=utf-8' to the headers as well.

Trying to use 'Postman' and having trouble setting Basic access authentication Headers

I have an API endpoint that I am trying to test with the google app: 'Postman'. I need to set the headers which use 'Basic authentication'. I am not sure what should go in 'Header: Value'
This is how the admin said the headers should be set:
"The head value is the word 'Basic' followed by your org name and your Api key separated by a colon and base64 encoded."
I have tried numerous things but I am not getting it quite right. The error I get is "Message: Token not set".
Your header field should look like this:
Header : Authorization
Value : Basic base64('YourOrgName:YourAPIKEY');
You can get the base64 value of your string here:
https://www.base64encode.org/
For example, for my-org-name:123key4api it should be bXktb3JnLW5hbWU6MTIza2V5NGFwaQ==.
The complete header would look like:
Authorization: Basic bXktb3JnLW5hbWU6MTIza2V5NGFwaQ==
Looks like you are facing trouble in getting the base64 value. Well you can make use of in-built function in Javscript as below.
Simply run below code in any JS runtime, (Simplest would be - open console tab in chrome developer tool)
"username:password!" // Here I used basic Auth string format
// Encode the plain string to base64
btoa("username:password!"); // output: "dXNlcm5hbWU6cGFzc3dvcmQh"
// Decode the base64 to plain string
atob("dXNlcm5hbWU6cGFzc3dvcmQh"); // output: "username:password!"
It's 2019 and with Version 6.5.3 we have a separate tab to use different kind of Authentication techniques.
For basic auth you just have to give username and password after selecting "Basic Auth" under Authentication tab
Putting it all together in a pre-request script
(and then use the access_token for oauth).
var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(e){var t="";var n,r,i,s,o,u,a;var f=0;e=Base64._utf8_encode(e);while(f<e.length){n=e.charCodeAt(f++);r=e.charCodeAt(f++);i=e.charCodeAt(f++);s=n>>2;o=(n&3)<<4|r>>4;u=(r&15)<<2|i>>6;a=i&63;if(isNaN(r)){u=a=64}else if(isNaN(i)){a=64}t=t+this._keyStr.charAt(s)+this._keyStr.charAt(o)+this._keyStr.charAt(u)+this._keyStr.charAt(a)}return t},decode:function(e){var t="";var n,r,i;var s,o,u,a;var f=0;e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");while(f<e.length){s=this._keyStr.indexOf(e.charAt(f++));o=this._keyStr.indexOf(e.charAt(f++));u=this._keyStr.indexOf(e.charAt(f++));a=this._keyStr.indexOf(e.charAt(f++));n=s<<2|o>>4;r=(o&15)<<4|u>>2;i=(u&3)<<6|a;t=t+String.fromCharCode(n);if(u!=64){t=t+String.fromCharCode(r)}if(a!=64){t=t+String.fromCharCode(i)}}t=Base64._utf8_decode(t);return t},_utf8_encode:function(e){e=e.replace(/\r\n/g,"\n");var t="";for(var n=0;n<e.length;n++){var r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r)}else if(r>127&&r<2048){t+=String.fromCharCode(r>>6|192);t+=String.fromCharCode(r&63|128)}else{t+=String.fromCharCode(r>>12|224);t+=String.fromCharCode(r>>6&63|128);t+=String.fromCharCode(r&63|128)}}return t},_utf8_decode:function(e){var t="";var n=0;var r=c1=c2=0;while(n<e.length){r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r);n++}else if(r>191&&r<224){c2=e.charCodeAt(n+1);t+=String.fromCharCode((r&31)<<6|c2&63);n+=2}else{c2=e.charCodeAt(n+1);c3=e.charCodeAt(n+2);t+=String.fromCharCode((r&15)<<12|(c2&63)<<6|c3&63);n+=3}}return t}};
var userPass = pm.environment.get("oauth_key") + ':' + pm.environment.get("oauth_secret")
pm.sendRequest({
url: pm.environment.get("basepath")+"/oauthpreview/token",
method: 'POST',
header: {
'Accept': 'application/json',
'cache-control':"no-cache",
'Authorization' : 'Basic ' + Base64.encode(userPass),
'Content-Type': 'application/x-www-form-urlencoded'
},
body: {
mode: 'urlencoded',
urlencoded: [
{key: "grant_type", value: "client_credentials", disabled: false}
]
}
}, function (err, res) {
pm.environment.set("access_token", res.json().access_token);
})

Promise response works with GET, but not with POST in XHR

I am trying to call a URL through XHR.post on the DOJO 1.8. I need catch the STATUS property and getHeader() from promise response, but the problem is, when I call my URL with POST I don't have any promise, and when I call with GET I have all properties that I need, but I only can send the request as POST.
The most strange is that I have another code in AngularJS which works well, this code does the same thing. I am testing DOJO and AngularJS.
I need catch the STATUS information to check if it is 201(created), if true I need catch getHeader('location') and call the URL that I picked up from getHeader('location').
Look at my method in Dojo 1.8:
checkCreation: function(typeFile, id){
var promise = xhr('/rest/list/one', {
handleAs: 'json',
method: 'post',
accepts: 'application/json',
headers: {
Accept: 'application/json',
id: id,
type: typeFile
}
});
promise.response.then(function(response) {
console.log("status", response.status);
console.log("options", response.options);
console.log("url", response.url);
console.log("timestamp", response.options.timestamp);
console.log(response);
});
},
I discovered the problem, I commented the lines followings and now works fine.
//handleAs: 'json',
//accepts: 'application/json',
The handleAs you need to use only when you have a JSON response. About "accepts" I haven't found what difference between "accept" and "Accept"(inside headers) yet.
Now I can take my informations:
console.log('location: ', response.getHeader('location'));
console.log("status: ", response.status);