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

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));
}

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

How to send Base64 to API

I am ultimately trying to send a fax with the Vitelity API. I have an API on EC2 that I am calling from my React Native app:
// Encoding to Base64
const encodeB64 = () => {
RNFS.readFile(croppedImage, 'base64').then(res => {
sendB64(res);
});
};
const sendB64 = b64 => {
let myHeaders = new Headers();
myHeaders.append('Content-Type', 'application/json');
let raw = JSON.stringify({
data1: b64, // 'jdl3439fdjsle/jjug'
login: {login},
pass: {pass},
faxnum: {destinationNum},
faxsrc: {sourceNum},
recname: 'Test',
file1: 'testfax.jpg',
});
let requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw,
redirect: 'follow',
};
fetch(API_URL, requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
};
However, this returns an error cannot POST. If, instead of b64, I change data1's value to something like jdl3439fdjsle/jjug, everything is great.
Do I need to do something special to b64 before I can send it?
My Base64 looks like: /9j/4AA{1.2m more chars}uB//9k=. I've pasted it into a converter and it produces the correct image.
I geuss you have to use a Multipart Form with multipart/form-data as content-type headers if you want to send images. See also this question.

Converting Javascript Fetch to Google Apps Script URL Fetch

Have the JavaScript code from a successful API call but when I try to change it to use Google Apps Scripts URL Fetch function I get an error.
Here's the JavaScript from successful Postman Call
...
var myHeaders = new Headers();
myHeaders.append("X-Auth-Token", "Token");
myHeaders.append("Content-Type", "application/json");
myHeaders.append("Cookie", "laravel_session=eyJpdiI6InpSaXcxVk1KQzd4cGMrT1BkWGlOQkQ0Tmt5TjhDRWRLVnlXQVwvYlJlV1EwPSIsInZhbHVlIjoiZGUyc21wWlZERHVJYkVhYks3MCswWXFOZllOQU5kSHdWeDJMbkdSZk5rNFV0N1BuUEI3N1FQT3RpbkhEU3JFRU56Wml4eE9NMmlKVGRqXC9OQ1pwNEJ3PT0iLCJtYWMiOiJjM2Q1NjBkYTAyMGFmNDY3NWJiY2VkMzZjODg0ZDViMDBlM2NmZDVkODBlMzk1YTc0ZTFlOGU4MTM3ODUxYjkxIn0%3D");
var raw = JSON.stringify({"description":"Test Description","invitees":"test#test.com","priority":"10","remind":{"popup":"0","mail":"1","hour":"09:00:00","date":"2020-12-22"},"sync_calendar":true,"task_name":"Test Name"});
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw,
redirect: 'follow'
};
fetch("https://private-anon-0eef3aeb66-ricochet.apiary-mock.com/api/v4/leads/lead_id/tasks/", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
...
And here is what I have in Google Apps Script
...
var raw = JSON.stringify({"description":"Test Description",
"invitees":"test#test.com",
"priority":"10",
"remind":{"popup":"0","mail":"1","hour":"09:00:00","date":"2020-12-22"},
"sync_calendar":true,
"task_name":"Test Name"});
var headers = { "X-Auth-Token" : "Token"};
var params = {
"method" : "POST",
'contentType': 'application/json',
"headers" : headers,
"payLoad" : raw
};
var url = "https://private-anon-0eef3aeb66-ricochet.apiary-mock.com/api/v4/leads/lead_id/tasks/";
var res = UrlFetchApp.fetch(url,params);
...
Here is the error I get when using Google Apps Script
Exception: Request failed returned code 500. Truncated server response: {"status":false,"message":"Validation failed"}

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