Post Request with forms (and JavaScript fetch()) - javascript

How can i send a form parameter in a post (JavaScript fetch()) request?
e.g.
curl --form "avatar=#me.jpg" "https://example.com/api/v4/endpoint"
I tried the folloing code:
const form = new FormData()
form.append("foo":"bar")
fetch( "https://someapi.org/api", {
method: 'POST',
headers:form
} )
.then( response => response.json() )
.then( response => {
console.log(response)
} );
}
which doesn't work for me.

The FormData should be supplied as the body property of the RequestInit, like this:
Make sure you use the correct Content-Type header. You can read about Using FormData Objects on MDN.
TS Playground
so-70865955.ts:
async function example () {
const form = new FormData();
form.append("foo", "bar");
const apiAddress = "https://someapi.org/api";
const init: RequestInit = {
method: 'POST',
headers: new Headers([['content-type', 'application/x-www-form-urlencoded']]),
body: form,
};
const response = await fetch(apiAddress, init);
const data = await response.json();
console.log(data);
}
// Invoke it
example();
In your console:
deno run --allow-net so-70865955.ts

Related

Why can't I send a form data from axios?

I am consuming an api that asks me to send a filter series within a formData, when doing the tests from Postman everything works without problem, I tried with other libraries and it also works without problem, but when trying to do it from axios the information does not return with the filters.
This is the code I am using:
const axios = require('axios');
const FormData = require('form-data');
let data = new FormData();
data.append('filtro_grafica', '2,0,0,0');
let config = {
method: 'get',
url: 'https://thisismyurl/filter',
headers: {
'Authorization': 'JWT MYTOKEN',
...data.getHeaders()
},
data : data
};
axios(config)
.then((response) => {
console.log(JSON.stringify(response.data));
})
.catch((error) => {
console.log(error);
});
You can send Form-data using get method, but the most servers, will reject the form data.
However it is not recommended anymore. The reason is, first because it is visible in the URL and browsers can cache them in it’s history backstacks, and second reason is because browsers have some limitations over the maximum number of characters in url.
If you are to send only few fields/input in the forms you can use it but if you have multiple inputs you should avoid it and use POST instead.
At the end it depends on your own usecase. Technically both GET and POST are fine to send data to server.
replace get with post
const axios = require('axios');
const FormData = require('form-data');
let data = new FormData();
data.append('filtro_grafica', '2,0,0,0');
let config = {
method: 'post',
url: 'https://thisismyurl/filter',
headers: {
'Authorization': 'JWT MYTOKEN',
...data.getHeaders()
},
data : data
};
axios(config)
.then((response) => {
console.log(JSON.stringify(response.data));
})
.catch((error) => {
console.log(error);
});

Issue with sending FormData from backend

I have a component which processes and uploads images. Currently I process the image on my backend and then send it to my frontend and then upload it from there. I would like to do everything on my backend. The only issue is that the upload endpoint requires FormData() object. I found an npm package form-data which I'm using on my backend now, but I'm still getting error.
This is how it currently works:
// frontend logic:
const data = await uploadImage(img);
const file = new File([Buffer.from(data)], `img-${i}.webp`, {
type: "image/webp",
});
const formData = new FormData();
formData.append("path", "images");
formData.append("files", file, file.name);
await axios
.post("http://localhost:1338/api/upload", formData, {
headers: { authorization: `Bearer ${jwtToken}` },
})
.then(({ data }) => {
console.log(data);
})
.catch(console.log);
//
//
// backend logic:
const data = await processImage(img.url);
return data;
This is what im trying to do:
// frontend logic:
const data = await uploadImage(img);
//
//
// backend logic:
const data = await processImage(img.url);
const formData = new FormData();
formData.append("path", "images");
formData.append("files", data, "file.name");
await axios
.post("http://localhost:1338/api/upload", formData, {
headers: { authorization: `Bearer ${process.env.JWT_TOKEN}` },
})
.then(({ data }) => {
console.log(data);
})
.catch(console.log); // I get error: 413 Payload Too Large
I'm trying to do it with the same image which works with the first method. Perhaps I need to create a new File(), but I couldn't find any npm packages which worked for that. What should I do to get this working?

How to replay a Puppeteer HTTPRequest?

Using Puppeteer, I am able to intercept HTTPResponses and their HTTPRequests:
page.on("response", async response => {
let request = response.request(); // Getting the response request
let responseHeaders = response.headers(); // Check response headers
response.buffer().then(buffer => {
// Play with response content
});
})
Depending on the response content, I need to send the request again like a fresh one and get its response buffer. Instantiating an identical and new request is a valid option.
I know I could use node-fetch as a last resort, but Puppeteer seems to have everything embedded to do it without adding packages.
Do you know how to achieve this?
Puppeteer HTTPRequest doc
Puppeteer HTTPRequest class
You can use page.evaluate to send a post request using fetch API
await page.evaluate(() => {
return fetch('url', {method: 'POST', body: 'test' }).then(res => res.json())
})
So then you can make a request after the requestfinished event fired.
page.setRequestInterception(true)
page.on('requestfinished', async (request: Request) => {
let response = request.response() // Getting the response request
let responseHeaders = response.headers() // Check response headers
let responseBuffer = await response.buffer() // Get the buffer required
let responseJSON = await response.json() // Get parsed JSON body
await page.evaluate(([headers, buffer, json]) => { // Replay request with buffer received
let someData1 = buffer.toString() // Change buffer to string type
let someData2 = headers['Content-Type'] // or maybe use some headers data
let someData3 = json.properties.value // or use response data object properties
// This fetch API below will do the rest
return fetch('url', { method: 'POST', body: 'test' }).then(res => res.json())
}, [responseHeaders, responseBuffer, responseJSON])
})

Expo Formdata does not working for to send a image to api rest

Hi Everybody i making a web frontend using expo SDK 39.0.2 but i have a big problend and really i not found a fix, im trying to send image like formdata to my backend but in mi backend this is null; this is not a problem of my api rest, i send a similar tequest from postman and all is’t working… but not working from formdata and I think : “this is problem with my way of to send formdata”
this is my code:
//Component code
const imagepreview = async()=>{
let result = await ImagePicker.launchImageLibraryAsync({
allowsEditing: false,
aspect: [4, 3],
quality: 0.6,
});
console.log(result)
if(result.cancelled == false){
setImage(result.uri)
let uriParts = result.uri.split('.');
let fileType = uriParts[uriParts.length - 1];
settype(fileType)
}
}
const sendData = async()=>{
// Upload the image using the fetch and FormData APIs
let formData = await new FormData();
// Assume "photo" is the name of the form field the server expects
await formData.append('photo', {
name: `photo.${type}`,
type: `image/${type}`,
uri: image,
});
const send = await user.changeprofilepicture(formData)
my http request code:
async changeprofilepicture(formdata){
console.log(formdata)
const token = JSON.parse(localStorage.getItem('user-token'))
let url = baseurl+'changeprofilepicture'
let options = {
headers: {
'content-type': 'multipart/form-data'
}
}
await axios.post(url, formdata, options)
await axios.post(url, {
photo: formdata
}, {headers :
{'Content-Type':undefined}})
}
i have two http request for im triying two ways for solved my broblem but does not works, only works at postman
really, thanks for te answers
Finally I solved..
I Change expo image picker for expo document picker like this:
const imagepreview = async()=>{
const trye = await DocumentPicker.getDocumentAsync({type: 'image/*'})
setFile(trye.file)
setImage(trye.uri)
console.log (trye)
}
const sendData = async()=>{
formData.append('photo', file);
console.log(file)
return await fetch('http://127.0.0.1:3333/api/changeprofilepicture', {
method: 'POST',
body: formData,
});
}

How to submit a file using Fetch API from an input element

A user will select an image and then i want to send this image to the backend.
The sending of an image is handled in the body, for example i have successfully tested on postman, i select body -> binary to upload an image directly.
I want to replicate this request using javascript fetch api.
Submission
<input id="front" class="inputfile" type="file" onchange="frontChange(this)">
async function frontChange(file) {
this.frontInput = file
}
async function done() {
const res = await this.submitDocument(this.frontInput.files[0]);
console.log(res);
}
Submit Document/File function
async submitDocument(doc) {
const url = <removed>;
const body = doc;
let headers = new Headers();
headers.set('Authorization', this.authorization);
const request = {
method: 'POST',
body: body,
headers: headers,
};
try {
const response = await fetch(url, request);
const data = await response.json();
return {
response: response,
data: data,
};
} catch (err) {
throw err;
}
}
It doesn't' seem like this works because. submitDocument throws a catch error
SyntaxError: Unexpected end of JSON input
Create a new FormData() and append to it the document,
e.g.
const form = new FormData();
form.append('file', doc);
And then send in your body request the form you have created.

Categories

Resources