I have route where I can upload images, and it works fine with postman.
I`m using multer as middleware.
var data = new FormData();
data.append("file", "");
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});
xhr.open("POST", "http://localhost:8080/file");
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.setRequestHeader("cache-control", "no-cache");
xhr.setRequestHeader("Postman-Token", "a6e7543e-ef94-4d17-813d-a0a1fb4aa2b2");
xhr.send(data);
but when I`m using fetch in my react app it just return undefined
uploadImage = async (image) => {
const imageData = new FormData()
imageData.append('file', image)
const address = '/file'
const body = imageData
const response = await fetch(`http://localhost:8080${address}`, {
method: 'POST',
credentials: 'include',
body: body
})
const result = await response.json()
return result
}
Any ideas how to fix it?
I copy paste request from postman to my react app, it still doesn`t work.
Related
I'm trying to test an endpoint which will upload a file and give 200 response status code in cypress. As per some research cy.request cannot be used to upload a file for multipart/form-data so we need to use XMLHttp to upload such files. I have created below file to test the api but it doesn't work. Can someone please help what's wrong with my code ? Thank you.
Added below code under support/commands.ts(I will require a header to pass token from auth endpoint)
// Performs an XMLHttpRequest instead of a cy.request (able to send data as FormData - multipart/form-data)
Cypress.Commands.add('multipartFormRequest', (method,URL, formData,headers, done) => {
const xhr = new XMLHttpRequest();
xhr.open(method, URL);
xhr.setRequestHeader("accept", "application/json");
xhr.setRequestHeader("Content-Type", "multipart/form-data");
if (headers) {
headers.forEach(function(header) {
xhr.setRequestHeader(header.name, header.value);
});
}
xhr.onload = function (){
done(xhr);
};
xhr.onerror = function (){
done(xhr);
};
xhr.send(formData);
})
Test file to call multipartFormRequest:
const fileName = 'test_file.txt';
const method = 'POST';
const URL = "https://fakeurl.com/upload-file";
const headers = api.headersWithAuth(`${authToken}`);
const fileType = "application/text";
cy.fixture(fileName, 'binary').then((res) => {
const blob = Cypress.Blob.binaryStringToBlob(res, fileType);
const formData = new FormData();
formData.append('file', blob, fileName);
cy.multipartFormRequest(method, URL, headers, formData, function (response) {
expect(response.status).to.equal(200);
})
})
I'm getting this error message:-
Now, I'm getting status code as 0.
describe("Upload image", () => {
it("upload first image", () => {
const fileName = "image.jpeg";
const method = "POST";
const url = "https://api-demo.com/1";
const fileType = "image/jpeg";
cy.fixture(fileName, "binary")
.then((txtBin) => Cypress.Blob.binaryStringToBlob(txtBin))
.then((blob) => {
const formData = new FormData();
formData.append("image_data", blob, fileName);
formData.append("image_format", "jpeg");
cy.form_request(method, url, formData, function (response) {
expect(response.status).to.eq(200)
}
);
})
});
});
Cypress.Commands.add('form_request', (method, url, formData, done) => {
const xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.setRequestHeader("device", "331231");
xhr.setRequestHeader("city", "bangalore");
xhr.onload = function () {
done(xhr);
};
xhr.onerror = function () {
done(xhr);
};
xhr.send(formData);
})
Use
const blob = Cypress.Blob.binaryStringToBlob(res, fileType);
and remove the .then().
See Cypress.Blob
History
Version 5.0.0
Changes:
Return type of arrayBufferToBlob, base64StringToBlob, binaryStringToBlob, and dataURLToBlob methods changed from Promise<Blob> to Blob
I am attempting to write a method so that i pass the url and application name and it return the response. I read that I can apply callback to resolve this but I am not able to resolve the issue. Any help would be appreciated.
Please find below my code snippet.
var response = getResponse(url,applicationName)
console.log("response from getResponse \n" +response);
function getResponse(url,applicationName){
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify({
"application": applicationName
}));
xhr.onload = function() {
console.log(this.responseText);
}
return xhr.responseText;
}
You can use the onreadystatechange method to handle XHR responses, try this:
//XHR POST
const xhr = new XMLHttpRequest; // creates new object
const url = 'https://api-to-call.com/endpoint';
const data = JSON.stringify({"application": applicationName}); // converts data to a string
xhr.responseType = 'json';
xhr.onreadystatechange = () => {
if(xhr.readyState === XMLHttpRequest.DONE) {
return xhr.response;
}
}
xhr.open('POST', url); // opens request
xhr.send(data); // sends object
you should use promise instead of callback and do something like that.
const url = "https://httpbin.org/post";
const applicationName = "test";
getResponse(url, applicationName)
.then(response => {
//work here, not outside
console.log(response);
})
.catch(error => {
console.log(error);
})
function getResponse(url, applicationName) {
return new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify({
"application": applicationName
}));
xhr.onload = function() {
// print JSON response
if (xhr.status >= 200 && xhr.status < 300) { // if valid
// work here
const response = JSON.parse(xhr.response.replace(/"/g, '"'));
const data = JSON.parse(response.data.replace(/"/g, '"'));
resolve(data);
}
reject(xhr.response); // reject and return the response if not valid
}
})
}
If you want to learn more about asynchronous https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Concepts, I invite you to go to this website to learn a little more about the promise.
https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Promises
The callback is executed after the code returned xhr.responseText. So that means xhr.responseText returns null.
I would recommend using the fetch API opposed to the older XMLHttpRequest you are using now. The fetch API is basically a Promise based XMLHttpRequest.
Your function would look something like:
async function getResponse( url, applicationName ) {
const json = JSON.stringify({
"application": applicationName
});
return fetch( url, {method: 'POST', headers: { 'Content-Type':'application/json'}, body: json} );
}
// access like this
getResponse( url, applicationName)
.then( response => { console.log(response) });
async function someFunction( url, applicationName ) {
// or pause the code while the request is fetched by using await, note that you need to be in a function that is declared async to use this approach.
const response = await getResponse( url, applicationName );
}
Fetch documentation can be found at MDN: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
I am trying to upload files to Google Drive via their api. When the file is over roughly 60MB it seems to be giving me a 404 or something went wrong screen.
I've tried several methods and noticed in 2015 alot of people were having similar issues because Google did not support resumable uploads from browser. I don't know if this has changed or not, but it seems to work fine for files under 60MB.
//const file = new File(['Hello, world!'], 'hello world.txt', { type: 'text/plain;charset=utf-8' });
const contentType = file.type || 'application/octet-stream';
const user = gapi.auth2.getAuthInstance().currentUser.get();
const oauthToken = user.getAuthResponse().access_token;
const initResumable = new XMLHttpRequest();
initResumable.open('POST', 'https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable', true);
initResumable.setRequestHeader('Authorization', 'Bearer ' + oauthToken);
initResumable.setRequestHeader('Content-Type', 'application/json');
initResumable.setRequestHeader('X-Upload-Content-Length', file.size);
initResumable.setRequestHeader('X-Upload-Content-Type', contentType);
initResumable.onreadystatechange = function () {
if (initResumable.readyState === XMLHttpRequest.DONE && initResumable.status === 200) {
const locationUrl = initResumable.getResponseHeader('Location');
const reader = new FileReader();
reader.onload = (e) => {
const uploadResumable = new XMLHttpRequest();
uploadResumable.open('PUT', locationUrl, true);
uploadResumable.setRequestHeader('Content-Type', contentType);
uploadResumable.setRequestHeader('X-Upload-Content-Type', contentType);
uploadResumable.onreadystatechange = function () {
if (uploadResumable.readyState === XMLHttpRequest.DONE && uploadResumable.status === 200) {
console.log(uploadResumable.response);
}
};
uploadResumable.send(reader.result);
};
reader.readAsArrayBuffer(file);
}
};
// You need to stringify the request body containing any file metadata
initResumable.send(JSON.stringify({
'name': file.name,
'mimeType': contentType,
'Content-Type': contentType,
'Content-Length': file.size
}));
How I can get response from graphql server using pure js without libraries?
For example how I can do that using XMLHttpRequest?
Query and serverUrl are below:
const serverUrl = 'http://example.com/graphql/'
const query = {
query: `{
viewer {
date
}
}`
};
Use POST request with 'Content-Type', 'application/json'
const yourServerUrl = 'http://example.com/graphql'
const yourQuery = {
query: `{
users {
firstName
}
}`
};
// below ordinary XHR request with console.log
const xhr = new XMLHttpRequest();
xhr.responseType = 'json';
xhr.open('POST', yourServerUrl);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onload = function () {
console.log('data returned:', xhr.response);
};
xhr.send(JSON.stringify(yourQuery));
source
I am trying to upload an image using fetch instead of xhr. My request works successfully when I use xhr. My xhr request object is the following
var data = new FormData();
var photoObject = {
uri: uriFromCameraRoll,
type: 'image/jpeg',
name: 'photo.jpg'
};
data.append("photos", photoObject);
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});
xhr.open("POST", "http://localhost:3000/api/v1/");
xhr.send(data);
Now I am trying to use fetch like following
fetch('http://localhost:3000/api/v1/', {
mode: 'no-cors',
method: 'POST' ,
body: data
}).then(function(response) {
console.log(response.status)
console.log(response)
})
But in my sever I am not receiving the file. Can anyone help me resolve this issue?