How to upload svg data using multipart/form-data? - javascript

I am trying to upload SVG data using fetch API and multipart/form-data content-type but its throwing 400 error code.
var myHeaders = new Headers();
myHeaders.append("Content-type", "multipart/form-data");
var formData = new FormData();
formData.append("front_svg",stage.canvas.toSVG());
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: formData,
redirect: 'follow'
};
fetch("api-url", requestOptions).then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));

Related

Unable to upload a github asset using Javascript

Overview
I'm attempting to upload asset to github using Javascript fetch request. It works in Postman
Postman
Error
but in javascript I get this error
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://uploads.github.com/repos/{owner}/{repo}/releases/{id}/assets?name=windows.zip. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 400.
I've been working on this for a few days now...
Thanks in advance
Javascript CODE
async function OpenFile() {
let input = document.createElement("input")
input.type = "file";
input.accept = "application/zip";
input.addEventListener("change", async e => {
let file = e.currentTarget.files[0];
let reader = new FileReader();
reader.addEventListener('load', () => {
let content = reader.result;
let myHeaders = new Headers();
myHeaders.append("Authorization", `token *****`);
myHeaders.append("Content-Type", "application/zip");
myHeaders.append("Accept", "application/vnd.github+json");
let requestOptions = {
method: 'POST',
headers: myHeaders,
body: content,
mode: 'cors'
};
fetch(`https://uploads.github.com/repos/{OWNER}/{REPO}/releases/{ID}/assets?name=file.zip`, requestOptions)
.then(response => response.json())
.then(json => {
console.log(JSON.stringify(json))
}).catch(error => { console.log(error) })
}, false)
reader.readAsArrayBuffer(file)
})
input.click();
}
P.S.
I removed sensitive information from the urls
Edit:
Github API states that you should be able to use this
// Octokit.js
// https://github.com/octokit/core.js#readme
const octokit = new Octokit({
auth: 'personal-access-token123'
})
await octokit.request('POST /repos/{owner}/{repo}/releases/{release_id}/assets{?name,label}', {
owner: 'OWNER',
repo: 'REPO',
release_id: 'RELEASE_ID'
})
OR
var myHeaders = new Headers();
myHeaders.append("Authorization", "token ******");
myHeaders.append("Content-Type", "application/zip");
var file = "<file contents here>";
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: file,
redirect: 'follow'
};
fetch("https://uploads.github.com/repos/{OWNER}/{REPO}/releases/{ID}/assets?name=file.zip", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));

“TypeError: Failed to fetch” when the request hasn’t actually failed Error

I'm using an API to make my login page validate the user and password with this code:
function ola() {
var myHeaders = new Headers();
myHeaders.append("Content-Type", "text/plain");
//WITH USERNAME AND PASSWORD LIKE THIS VVVVVV
var raw = "{\r\n \"password\": \"Olasou1!\",\r\n \"username\": \"bernardo\"\r\n}\r\n";
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw,
redirect: 'follow'
};
fetch("https://api.secureme.pt/api/v1/auth/login", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
};
I get a success message so I know that it worked
But when I try to use the user inputs on the variable raw like this:
function ola() {
var user = document.getElementById("user").value;
var password = document.getElementById("password").value;
var myHeaders = new Headers();
myHeaders.append("Content-Type", "text/plain");
var raw = {
password: password,
username: user
};
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw,
redirect: 'follow'
};
fetch("https://api.secureme.pt/api/v1/auth/login", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
};
And when I put the same username and password, I get an error saying that it failed to fetch:
error TypeError: Failed to fetch
at ola (:5500/js/loginRegister.js:36:3)
at HTMLButtonElement.onclick (loginRegister.html:22:74)
I can't figure out why, can someone help me with this?
This is where I call the function on html file:
<button type="submit" class="submit-btn" onclick="ola()">Log In</button>
Try to serialize your raw data:
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: JSON.stringify(raw),
redirect: 'follow'
}
You can check fetch documents for more details about which data types allowed by request body:
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#body
https://developer.mozilla.org/en-US/docs/Web/API/fetch#parameters

react js fetch api using file upload not being sent to body

Here is my code
let formData = new FormData();
// Update the formData object
formData.append(
"myFile",
this.state.product_picture,
this.state.product_picture.name
);
var options = { content: formData };
const token = JSON.parse(localStorage.getItem('token'));
const requestOptions = {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
product_name:this.state.product_name,
product_description:this.state.product_description,
product_picture:formData,
category_name:this.state.category_choosen,
})
};
fetch('http://cms.test/api/products/insert_supplier_product?token='+token, requestOptions)
.then(response => response.json())
.then(data => {
this.setState({ product: data.product})
})
.catch(error =>{
console.log("Product creation error", error);
});
I have this fetch api its always giving a 422 response I think what is happening is that its not reading a file as I want to upload a file it all works in postman but when using react it crashes
The body here is the problem
inside the state there are some strings but inside the this.state.product_picture there is a file
Hope someone can help! Thank you!
SOLUTION: Using axios to call the api solved my problem
You cannot send a file in a JSON object in a request( atleast not without Base64 encoding it). Change your code in the following way to send a file with your form.
let formData = new FormData();
// Update the formData object
formData.append(
"myFile",
this.state.product_picture,
this.state.product_picture.name
);
formData.append("product_name",this.state.product_name);
formData.append("product_description",this.state.product_description);
formData.append("category_name",this.state.category_choosen);
var options = { content: formData };
const token = JSON.parse(localStorage.getItem('token'));
const requestOptions = {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data',
},
body: formData
};
fetch('http://cms.test/api/products/insert_supplier_product?token='+token, requestOptions)
.then(response => response.json())
.then(data => {
this.setState({ product: data.product})
})
.catch(error =>{
console.log("Product creation error", error);
});

How to send a request to a Heroku app through another webpage?

I have a herokuapp deployed on heroku and it can pass all of my postman test. However, when I try to send a request to the herokuapp link through fetch using another project's button, it always fail and break the herokuapp. I'm trying to use the herokuapp as a server and it is already connected with my mongo database.
I copy pasted the code from var myHeaders straight from postman's code generating function.
Here is the code for my request, I have a username and a password input on the page and this function is designed for the sign in button:
function signin() {
var username = document.getElementById("username").value;
var password = document.getElementById("password").value;
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/x-www-form-urlencoded");
myHeaders.append("Content-Type", "application/x-www-form-urlencoded");
var urlencoded = new URLSearchParams();
urlencoded.append("username", "dandan");
urlencoded.append("password", "123");
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: urlencoded,
redirect: 'follow'
***mode: 'no-cors'***// This will make it work, but I don't know why
};
fetch("https://emma-game-server.herokuapp.com/signin", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
[UPDATED] I figured out adding mode:'no-cors' will give me the response, but as a noob I don't totally understand.
[UPDATED AGAIN] I figured out that I don't need 'no-cors' and I need to change the request form, here's the final alteration that worked:
function signin() {
var username = document.getElementById("username").value;
var password = document.getElementById("password").value;
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
var raw = JSON.stringify({"username":username,"password":password});
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw,
redirect: 'follow'
};
fetch("https://emma-game-server.herokuapp.com/signin", requestOptions)
.then(response => response.json())
.then(result => {
console.log(result);
if (result.success){
alert("Signed in as " + result.username);
document.getElementById("user").innerHTML=username;
}
else{
alert(result.message);
}
})
.catch(error => console.log('error', error));
}

Creating form data without using FormData in node-fetch

I'm using node fetch to make API Calls inside a platform.
I need to make an API Call to pass file in form-data.
Below is my stub code:
const fetch = require("node-fetch")
var myHeaders = {"Authorization": "Basic Y2hhdEJvdDpJRkxjYkAxMjM="
,'cache-control': 'no-cache'
,"content-type": "multipart/form-data;"
};
let file_content = "base 64 file content";
let getFormDataForWhatsAppStatement = (data,fileContent,fileExt)=>{
let jsonData = { "data":{ "templateName":"Test_123", "fieldName":"Document_Purpose,Policy_Number,Document_Category", "fieldValue":`AttachDocument, ${data.policyNumber}, Customer_Requirement`, "docList":"Test_Doc" } }
let formDataPairs = [];
let finalFormData = '';
formDataPairs.push(encodeURIComponent("") + '=' + encodeURIComponent(jsonData));
formDataPairs.push(encodeURIComponent("") + '=' + encodeURIComponent(fileContent));
finalFormData = formDataPairs.join('&').replace(/%20/g, '+');
return finalFormData;
}
let formdata = getFormData({"policyNumber":"006558144"},file_content,"png");
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: formdata
};
fetch(url, requestOptions)
.then(response => response.json())
.then(result => console.log(result))
.catch(error => console.log('error', error));
The error I get here is boundary parameter is not defined.
So I removed the content-type header as stated in the below thread:
Boundary Issue
But then it gives me connection timeout error(since the request format is incorrect).
So is there a way to create formData Similar to the below code without using FormData Object?
const FormData = require('form-data');
const fetch = require("node-fetch")
var formdata = new FormData();
var myHeaders = {"Authorization": "Basic Y2hhdEJvdDpJRkxjYkAxMjM="
//,"Content-Type": "multipart/form-data; boundary=----WebKitFormBoundaryyEmKNDsBKjB7QEqu"
};
formdata.append("", "{ \n \"data\":{ \n\n \"templateName\":\"Test_123\",\n \"fieldName\":\"Document_Purpose,Policy_Number,Document_Category\",\n \"fieldValue\":\"AttachDocument, G0000784, Customer_Requirement\",\n \"docList\":\"Test_Doc\" \n}\n}\n");
formdata.append("", "base 64 file data", "close.png");
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: formdata,
redirect: 'follow'
};
fetch(API_URL, requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
Instead of literally inputting the boundary have you tried using the form-data function getBoundary() and assigning it to a variable like so:
let boundary = formdata.getBoundary();
var myHeaders = {"Authorization": "Basic Y2hhdEJvdDpJRkxjYkAxMjM="
"Content-Type": `multipart/form-data; boundary=${boundary}`
};

Categories