Error while sending a request to fluxpoint api - javascript

it's me again... Sorry for asking so many times a day, but I'm really an idiot.
So basically I'm trying to send a request to the fluxpoint api by using this code:
async welcome(username, avatarurl, background, membercount, icon, backgroundname, filename){
let req = {}
req.username = username;
req.avatar = avatarurl;
if (background == null) {req.background = "#aaaaaa"} else {req.background = background}
if (membercount) req.members = "Member #"+membercount
if (icon) req.icon = icon
if (backgroundname) req.banner = backgroundname
console.log(req)
let usedClient = axios.create({
baseURL: apiUrls[0],
timeout: 5000,
headers: {
'Authorization': this.token,
'Content-Length': 0,
'Content-Type': 'application/json'
},
data: JSON.parse(req),
responseType: 'arraybuffer'
})
console.log(usedClient)
console.log(apiUrls[0]+api1endpoints[1])
let res = await usedClient.get(api1endpoints[1])
return res
}
Here is the code I'm using for testing it:
const fluxpoint = require('./index')
const Client = new fluxpoint.Client("my fluxpoint token")
async function tt(){
let t = await Client.welcome("Koro~ (Baka)#7963", "https://cdn.discordapp.com/avatars/304541381798658048/36806f6ae648b9ebc8303443b0be101c.png", "#FFFFFF", 1, "neko", "space")
console.log(t)
}
tt()
And, here is the error the fluxpoint api sends me:
Failed to parse json, The input does not contain any JSON tokens. Excepted the input to start with a valid JSON token, when isFinalBlock is true. Path: $ | LineNumber: 0 | BytePositionInLine: 0.
I tried everything, but JSON.parse(my data) sends me Unexcepted token o in JSON at position 1
I'm being desesperate and I hope somebody can help me!

It seems you are parsing the raw json.It throws an error
JSON.parse takes string as parameter.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse
And from official doc you cannot use data in get request.
https://github.com/axios/axios#request-config
// `data` is the data to be sent as the request body
// Only applicable for request methods 'PUT', 'POST', and 'PATCH'
// When no `transformRequest` is set, must be of one of the following types:
// - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
// - Browser only: FormData, File, Blob
// - Node only: Stream, Buffer
data: {
firstName: 'Fred'
}
So try passing the data
let res = await usedClient.get(api1endpoints[1],{
params: {
data: res
}
})
I've tested the endpoint it works only if responseType is 'text' or 'stream'

Related

ECONNRESET and CGI parser error when trying to upload file using axios post [duplicate]

I have an API endpoint that lets the client post their csv to our server then post it to someone else server. I have done our server part which save uploaded file to our server, but I can't get the other part done. I keep getting error { message: 'File not found', code: 400 } which may mean the file never reach the server. I'm using axios as an agent, does anyone know how to get this done? Thanks.
// file = uploaded file
const form_data = new FormData();
form_data.append("file", fs.createReadStream(file.path));
const request_config = {
method: "post",
url: url,
headers: {
"Authorization": "Bearer " + access_token,
"Content-Type": "multipart/form-data"
},
data: form_data
};
return axios(request_config);
Update
As axios doc states as below and the API I'm trying to call requires a file
// data is the data to be sent as the request body
// Only applicable for request methods 'PUT', 'POST', and 'PATCH'
// When no transformRequest is set, must be of one of the following types:
// - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
// - Browser only: FormData, File, Blob
// - Node only: Stream, Buffer
Is there any way to make axios send a file as a whole? Thanks.
The 2 oldest answers did not work for me. This, however, did the trick:
const FormData = require('form-data'); // npm install --save form-data
const form = new FormData();
form.append('file', fs.createReadStream(file.path));
const request_config = {
headers: {
'Authorization': `Bearer ${access_token}`,
...form.getHeaders()
}
};
return axios.post(url, form, request_config);
form.getHeaders() returns an Object with the content-type as well as the boundary.
For example:
{ "content-type": "multipart/form-data; boundary=-------------------0123456789" }
I'm thinking the createReadStream is your issue because its async. try this.
Since createReadStream extends the event emitter, we can "listen" for when it finishes/ends.
var newFile = fs.createReadStream(file.path);
// personally I'd function out the inner body here and just call
// to the function and pass in the newFile
newFile.on('end', function() {
const form_data = new FormData();
form_data.append("file", newFile, "filename.ext");
const request_config = {
method: "post",
url: url,
headers: {
"Authorization": "Bearer " + access_token,
"Content-Type": "multipart/form-data"
},
data: form_data
};
return axios(request_config);
});
This is what you really need:
const form_data = new FormData();
form_data.append("file", fs.createReadStream(file.path));
const request_config = {
headers: {
"Authorization": "Bearer " + access_token,
"Content-Type": "multipart/form-data"
},
data: form_data
};
return axios
.post(url, form_data, request_config);
In my case, fs.createReadStream(file.path) did not work.
I had to use buffer instead.
const form = new FormData();
form.append('file', fs.readFileSync(filePath), fileName);
const config = {
headers: {
Authorization: `Bearer ${auth.access_token}`,
...form.getHeaders(),
},
};
axios.post(api, form.getBuffer(), config);
I have made an interceptor you can connect to axios to handle this case in node: axios-form-data. Any feedback would be welcome.
npm i axios-form-data
example:
import axiosFormData from 'axios-form-data';
import axios from 'axios';
// connect axiosFormData interceptor to axios
axios.interceptors.request.use(axiosFormData);
// send request with a file in it, it automatically becomes form-data
const response = await axios.request({
method: 'POST',
url: 'http://httpbin.org/post',
data: {
nonfile: 'Non-file value',
// if there is at least one streamable value, the interceptor wraps the data into FormData
file: createReadStream('somefile'),
},
});
// response should show "files" with file content, "form" with other values
// and multipart/form-data with random boundary as request header
console.log(response.data);
I had a same issue, I had a "pdf-creator-service" for generate PDF document from html.
I use mustache template engine for create HTML document - https://www.npmjs.com/package/mustache
Mustache.render function returns html as a string what do I need to do to pass it to the pdf-generator-service ? So lets see my suggestion bellow
//...
async function getPdfDoc(props: {foo: string, bar: string}): Promise<Buffer> {
const temlateFile = readFileSync(joinPath(process.cwd(), 'file.html'))
mustache.render(temlateFile, props)
const readableStream = this.getReadableStreamFromString(htmlString)
const formData = new FormData() // from 'form-data'
formData.append('file', options.file, { filename: options.fileName })
const formHeaders = formData.getHeaders()
return await axios.send<Buffer>(
{
method: 'POST',
url: 'https://pdf-generator-service-url/pdf',
data: formData,
headers: {
...formHeaders,
},
responseType: 'arraybuffer', // ! important
},
)
}
getReadableStreamFromString(str: string): Readable {
const bufferHtmlString = Buffer.from(str)
const readableStream = new Readable() // from 'stream'
readableStream._read = () => null // workaround error
readableStream.push(bufferHtmlString)
readableStream.push(null) // mark end of stream
return readableStream
}
For anyone who wants to upload files from their local filesystem (actually from anywhere with the right streams architecture) with axios and doesn't want to use any external packages (like form-data).
Just create a readable stream and plug it right into axios request function like so:
await axios.put(
url,
fs.createReadStream(path_to_file)
)
Axios accepts data argument of type Stream in node context.
Works fine for me at least in Node v.16.13.1 and with axios v.0.27.2

how to add file with formData in axios request using node.js [duplicate]

I have an API endpoint that lets the client post their csv to our server then post it to someone else server. I have done our server part which save uploaded file to our server, but I can't get the other part done. I keep getting error { message: 'File not found', code: 400 } which may mean the file never reach the server. I'm using axios as an agent, does anyone know how to get this done? Thanks.
// file = uploaded file
const form_data = new FormData();
form_data.append("file", fs.createReadStream(file.path));
const request_config = {
method: "post",
url: url,
headers: {
"Authorization": "Bearer " + access_token,
"Content-Type": "multipart/form-data"
},
data: form_data
};
return axios(request_config);
Update
As axios doc states as below and the API I'm trying to call requires a file
// data is the data to be sent as the request body
// Only applicable for request methods 'PUT', 'POST', and 'PATCH'
// When no transformRequest is set, must be of one of the following types:
// - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
// - Browser only: FormData, File, Blob
// - Node only: Stream, Buffer
Is there any way to make axios send a file as a whole? Thanks.
The 2 oldest answers did not work for me. This, however, did the trick:
const FormData = require('form-data'); // npm install --save form-data
const form = new FormData();
form.append('file', fs.createReadStream(file.path));
const request_config = {
headers: {
'Authorization': `Bearer ${access_token}`,
...form.getHeaders()
}
};
return axios.post(url, form, request_config);
form.getHeaders() returns an Object with the content-type as well as the boundary.
For example:
{ "content-type": "multipart/form-data; boundary=-------------------0123456789" }
I'm thinking the createReadStream is your issue because its async. try this.
Since createReadStream extends the event emitter, we can "listen" for when it finishes/ends.
var newFile = fs.createReadStream(file.path);
// personally I'd function out the inner body here and just call
// to the function and pass in the newFile
newFile.on('end', function() {
const form_data = new FormData();
form_data.append("file", newFile, "filename.ext");
const request_config = {
method: "post",
url: url,
headers: {
"Authorization": "Bearer " + access_token,
"Content-Type": "multipart/form-data"
},
data: form_data
};
return axios(request_config);
});
This is what you really need:
const form_data = new FormData();
form_data.append("file", fs.createReadStream(file.path));
const request_config = {
headers: {
"Authorization": "Bearer " + access_token,
"Content-Type": "multipart/form-data"
},
data: form_data
};
return axios
.post(url, form_data, request_config);
In my case, fs.createReadStream(file.path) did not work.
I had to use buffer instead.
const form = new FormData();
form.append('file', fs.readFileSync(filePath), fileName);
const config = {
headers: {
Authorization: `Bearer ${auth.access_token}`,
...form.getHeaders(),
},
};
axios.post(api, form.getBuffer(), config);
I have made an interceptor you can connect to axios to handle this case in node: axios-form-data. Any feedback would be welcome.
npm i axios-form-data
example:
import axiosFormData from 'axios-form-data';
import axios from 'axios';
// connect axiosFormData interceptor to axios
axios.interceptors.request.use(axiosFormData);
// send request with a file in it, it automatically becomes form-data
const response = await axios.request({
method: 'POST',
url: 'http://httpbin.org/post',
data: {
nonfile: 'Non-file value',
// if there is at least one streamable value, the interceptor wraps the data into FormData
file: createReadStream('somefile'),
},
});
// response should show "files" with file content, "form" with other values
// and multipart/form-data with random boundary as request header
console.log(response.data);
I had a same issue, I had a "pdf-creator-service" for generate PDF document from html.
I use mustache template engine for create HTML document - https://www.npmjs.com/package/mustache
Mustache.render function returns html as a string what do I need to do to pass it to the pdf-generator-service ? So lets see my suggestion bellow
//...
async function getPdfDoc(props: {foo: string, bar: string}): Promise<Buffer> {
const temlateFile = readFileSync(joinPath(process.cwd(), 'file.html'))
mustache.render(temlateFile, props)
const readableStream = this.getReadableStreamFromString(htmlString)
const formData = new FormData() // from 'form-data'
formData.append('file', options.file, { filename: options.fileName })
const formHeaders = formData.getHeaders()
return await axios.send<Buffer>(
{
method: 'POST',
url: 'https://pdf-generator-service-url/pdf',
data: formData,
headers: {
...formHeaders,
},
responseType: 'arraybuffer', // ! important
},
)
}
getReadableStreamFromString(str: string): Readable {
const bufferHtmlString = Buffer.from(str)
const readableStream = new Readable() // from 'stream'
readableStream._read = () => null // workaround error
readableStream.push(bufferHtmlString)
readableStream.push(null) // mark end of stream
return readableStream
}
For anyone who wants to upload files from their local filesystem (actually from anywhere with the right streams architecture) with axios and doesn't want to use any external packages (like form-data).
Just create a readable stream and plug it right into axios request function like so:
await axios.put(
url,
fs.createReadStream(path_to_file)
)
Axios accepts data argument of type Stream in node context.
Works fine for me at least in Node v.16.13.1 and with axios v.0.27.2

Sending multiple cookies using Fetch in javascript

I am trying to send two cookies using Fetch in Javascript.
This is my function:
var cid_and_auth = process.argv[2];
const fetch = require("node-fetch");
function usePairService()
{
cid = cid_and_auth.split(" ")[1];
auth = cid_and_auth.split(" ")[0];
(async () => {
await fetch(AUTHENTICATIONURL, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': CONTENTTYPE,
'wpay-meta': userPairwpaymeta,
'cookie': 'cid'=cid,'auth'= auth,
},
body: JsonBody,
})
});;
}
I am trying to send cookies in the header, but it's giving an error, saying invalid left-hand die in expression. Any help will be appreciated.
'cid'=cid tries to assign the value of cid to the string value 'cid'. You cannot assign to a string, hence the error.
You have to build up a string of <key>=<value>; pairs. If you have each value in a variable you can either manually build the string, e.g. using template literals:
{
// ...
Cookie: `cid=${cid};auth=${auth}`,
}
or you could create an object from those variables and programmatically create the string (which makes it a bit easier to add more values later on):
const cookieData = {cid, auth};
// ...
{
// ...
Cookie: Object.entries(cookieData)
.map(([key, value]) => `${key}=${value}`)
.join(';'),
}

MERN Stack, axios post current state to DB error 400 bad request [duplicate]

I am trying to create a postHTTP request with some form parameters that are to be set. I am using the axios with node server. I already have a java code implementation of constructing a url as given below:
JAVA CODE:
HttpPost post = new HttpPost(UriBuilder.fromUri (getProperty("authServerUrl"))
.path(TOKEN_ACCESS_PATH).build(getProperty("realm")));
List<NameValuePair> formParams = new ArrayList<NameValuePair>();
formParams.add(new NameValuePair("username",getProperty ("username")));
formParams.add(new NameValuePair("password",getProperty ("password")));
formParams.add(new NameValuePair("client_id, "user-client"));
I am trying to do the same thing in axios.
AXIOS IMPLEMENTATION:
axios.post(authServerUrl +token_access_path,
{
username: 'abcd', //gave the values directly for testing
password: '1235!',
client_id: 'user-client'
}).then(function(response) {
console.log(response); //no output rendered
}
Is the approach to set these form params on the post request correct?
You have to do the following:
var querystring = require('querystring');
//...
axios.post(authServerUrl + token_access_path,
querystring.stringify({
username: 'abcd', //gave the values directly for testing
password: '1235!',
client_id: 'user-client'
}), {
headers: {
"Content-Type": "application/x-www-form-urlencoded"
}
}).then(function(response) {
console.log(response);
});
If your target runtime supports it, Axios is able to accept a URLSearchParams instance which will also set the appropriate Content-type header to application/x-www-form-urlencoded
axios.post(authServerUrl + token_access_path, new URLSearchParams({
username: 'abcd', //gave the values directly for testing
password: '1235!',
client_id: 'user-client'
}))
The same goes for the fetch API
fetch(url, {
method: "POST",
body: new URLSearchParams({
your: "object",
props: "go here"
})
})
Why pull in another library or module to do something so simple with pure vanilla JavaScript? It's really one line of JS to produce the desired data to submit in your POST request.
// es6 example
const params = {
format: 'json',
option: 'value'
};
const data = Object.keys(params)
.map((key) => `${key}=${encodeURIComponent(params[key])}`)
.join('&');
console.log(data);
// => format=json&option=value
const options = {
method: 'POST',
headers: { 'content-type': 'application/x-www-form-urlencoded' },
data,
url: 'https://whatever.com/api',
};
const response = await axios(options); // wrap in async function
console.log(response);
I agree with jhickok, no need to pull in an additional library however their code will not produce a correct result due to the usage of Object.entries, you would expect to see the following:
"format,json=0&option,value=1"
Instead Object.keys should be used.
const obj = {
format: 'json',
option: 'value'
};
const data = Object.keys(obj)
.map((key, index) => `${key}=${encodeURIComponent(obj[key])}`)
.join('&');
console.log(data); // format=json&option=value
Then of course...
const options = {
method: 'POST',
headers: { 'content-type': 'application/x-www-form-urlencoded' },
data,
url: 'https://whatever.com/api',
};
const response = await axios(options);
const body = new URLSearchParams();
body.append('param1', 'param1_value');
...
...
axios.post(url,body)

POST req: Only absolute URLs are supported

I am writing this app.js client file that performs a post request to a server (code below):
const fetch = require('node-fetch');
/* Function to POST data */
const postData = async ( url = 'http://localhost/8000/add/', data = {})=>{
console.log(data)
const response = await fetch(url, {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data) // body data type must match "Content-Type" header
});
try {
const newData = await response.json();
console.log(newData);
return newData
}catch(error) {
console.log("errors", error);
// appropriately handle the error
}
}
// TODO-Call Function
postData('/addAnimal', {animal: 'girrafe'});
I keep on getting this error when I run with node app.js:
node .\app.js
{ animal: 'girrafe' }
D:\Downloads\FEWD\WebAPIs\N&E\node_modules\node-fetch\lib\index.js:1305
throw new TypeError('Only absolute URLs are supported');
^
TypeError: Only absolute URLs are supported
at getNodeRequestOptions (D:\Downloads\FEWD\WebAPIs\N&E\node_modules\node-fetch\lib\index.js:1305:9)
D:\Downloads\FEWD\WebAPIs\N&E\node_modules\node-fetch\lib\index.js:1305
throw new TypeError('Only absolute URLs are supported');
^
TypeError: Only absolute URLs are supported
at getNodeRequestOptions (D:\Downloads\FEWD\WebAPIs\N&E\node_modules\node-fetch\lib\index.js:1305:9)
at D:\Downloads\FEWD\WebAPIs\N&E\node_modules\node-fetch\lib\index.js:1410:19
at new Promise (<anonymous>)
at fetch (D:\Downloads\FEWD\WebAPIs\N&E\node_modules\node-fetch\lib\index.js:1407:9)
at postData (D:\Downloads\FEWD\WebAPIs\N&E\demo\app.js:22:31)
at Object.<anonymous> (D:\Downloads\FEWD\WebAPIs\N&E\demo\app.js:42:3)
Any suggestion as to why, would be much appreciated.
Thank you
Your url = 'http://localhost/8000/add' sets the default parameter to that URL, then you overwrite it with '/addAnimal' when you provide that as an argument. You should provide an absolute URL:
postData('http://localhost/8000/addAnimal', {animal: 'girrafe'});
As a side note, I'm pretty sure localhost/8000 is a typo and should be localhost:8000.

Categories

Resources