I'm trying to upload a cropped image via client using fetch. The upload process works, the file size seems to be correct too but the uploaded image is corrupt and appears to be a white 16x16 square on the server. The file won't open when I download it (damaged or corrupt). I'm struggling to understand what I'm doing wrong. The back-end is Drupal.
Uploading files directly from an input using the same postFile function works without a problem.
const toFile = (blob) => {
blob.lastModifiedDate = new Date();
blob.name = 'cropped.png';
return blob;
}
const onCropperCrop = () => {
const imageElement = cropperRef?.current;
const cropper = imageElement?.cropper;
cropper.getCroppedCanvas().toBlob((blob) => {
const file = toFile(blob);
onCrop(file);
});
};
const onCrop = (file) => postFile(params);
export const postFile = async (
_file,
_uri,
_xcsrf_token,
_accessToken,
) => {
let formData = new FormData();
formData.append('File', _file);
let headers = {
headers: {
Accept: 'application/hal+json',
'Content-Type': 'application/octet-stream',
'Content-Disposition': 'file; filename="' + _file.name + '"',
'X-CSRF-Token': _xcsrf_token,
Authorization: 'Bearer ' + _accessToken,
},
};
return await fetch(_uri, {
method: 'POST',
headers: headers,
body: formData,
credentials: 'include'
});
};
The file object:
Related
So, I am creating a docx with php laravel, then converting to pdf and save it in my public server folder. Finally, I am sending a response to my client with the file.
Now, in client side, I am tryng to download it.
It's half working, because I can download a file (with exact same page number) but the file and all the page are blank page.
Here, server side sending my file to client side
$docx->transformDocument($fileName . '.docx', $fileName . '.pdf');
return response()->file(public_path($fileName . '.pdf'));
What I have tried client side
export const generateDocx = (offerData) => async () => {
await axios({
method: 'post',
url: `${process.env.REACT_APP_API_URL2}offer/generate/docx`,
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
responseType: 'arraybuffer',
},
data: offerData,
}).then((res) => {
console.log(res);
// Create blob link to download
const url = window.URL.createObjectURL(new Blob([res.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', `FileName.pdf`);
document.body.appendChild(link);
link.click();
link.parentNode.removeChild(link);
});
};
what my console.log (res) contain :
I have also tried this :
let fileName = 'aaa.pdf';
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(
new Blob([res.data], {
type: 'application/pdf',
encoding: 'UTF-8',
responseType: 'blob'
}),
fileName
);
} else {
const url = window.URL.createObjectURL(
new Blob([res.data], {
type: 'application/pdf',
encoding: 'UTF-8',
})
);
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', fileName);
document.body.appendChild(link);
link.click();
link.remove();
}
console.log(res.data);
});
And with file-saver package
var blob = new Blob([res.data], {
type: 'application/pdf',
});
saveAs(blob, 'hello world.pdf');
});
what my blob console.log contain :
After some test it's working
export const generateDocx = (offerData) => async () => {
await axios({
method: 'post',
url: `${process.env.REACT_APP_API_URL2}offer/generate/docx`,
responseType: 'blob',
headers: {
Accept: 'application/pdf',
},
data: offerData,
}).then((res) => {
var blob = new Blob([res.data], {
type: 'application/pdf',
});
saveAs(blob, 'test.pdf');
});
};
thank you all for your help
TDLR: Using s3 presigned post url to upload file to s3. Works fine on the browser but fails on the server.
I have a simple lambda function that generates presigned post url that can be consumed either in the browser or in the server.
During testing I noticed that the upload works fine one the browser but fails if I try to upload a file from a server even tho the code is identical.
The error i get is:
You must provide the Content-Length HTTP header
Detailed error:
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>MissingContentLength</Code>
<Message>You must provide the Content-Length HTTP header.</Message>
<RequestId>JP75YMFARK0G3X5Z</RequestId>
<HostId>toHsKmxmVYYAtac94cQoy8wXoregKG3PNBm97c3gQewEmKxLggcumTAP882T/pJNWx/lxRgH98A=</HostId>
</Error>
Request failed with status code 411
I checked online and found many threads about this issue but unfortunately not a single suggestion helped me.
Code I am running in the server
const axios = require('axios');
const { createReadStream, readFileSync } = require('fs');
const FormData = require('form-data');
const getPostPresignedUrl = async () => {
var config = {
method: 'post',
url: LAMBDA_GET_URL,
headers: {
'Content-Type': 'application/json',
},
data: JSON.stringify({
key: 'test-2.jpg',
fileType: 'image/jpeg',
}),
};
const {
data: { data },
} = await axios(config);
return data;
};
const uploadFileToS3 = async (fields, url) => {
const formData = new FormData();
Object.entries(fields).map(([key, value]) => {
formData.append(key, value);
});
const file = createReadStream('./test-1.jpg');
formData.append('file', file);
try {
const { data } = await axios({
url,
method: 'post',
headers: {
'Content-Type': 'multipart/form-data',
},
data: formData,
});
} catch (error) {
if (error instanceof axios.AxiosError) {
console.log(error.response.data);
}
console.log(error.message);
}
};
const init = async () => {
const { fields, url } = await getPostPresignedUrl();
await uploadFileToS3(fields, url);
};
init();
Code I am running in the browser:
const form = document.getElementById('form');
const input = document.getElementById('file');
const getPostPresignedUrl = async (name) => {
var config = {
method: 'post',
url: LAMBDA_GET_URL,
headers: {
'Content-Type': 'application/json',
},
data: JSON.stringify({
key: name,
fileType: 'image/jpeg',
}),
};
const {
data: { data },
} = await axios(config);
return data;
};
const uploadFileToS3 = async (fields, url, file) => {
const formData = new FormData();
Object.entries(fields).map(([key, value]) => {
formData.append(key, value);
});
formData.append('file', file);
try {
const { data } = await axios({
url,
method: 'post',
headers: {
'Content-Type': 'multipart/form-data',
},
data: formData,
});
} catch (error) {
if (error instanceof axios.AxiosError) {
console.log(error.response.data);
}
console.log(error.message);
}
};
const handleSubmit = async (e) => {
e.preventDefault();
const file = input.files[0];
const data = await getPostPresignedUrl(file.name);
await uploadFileToS3(data.fields, data.url, file);
};
form.onsubmit = handleSubmit;
I am trying to open pdf from the cloud in a new tab, without downloading it to the local machine.
I tried this way but not working for me. In the new tab, it is giving an error.
function readFileInNewTab (fileId) {
let url = BASE_URL + "api/CMS/Documents/Download/" + fileId;
const requestOptions = {
method: 'GET',
headers: { 'Content-Type': 'application/pdf', ...authHeader(url) },
credentials: 'include',
responseType: "blob", // important
};
inProgress = true;
return fetch (url, requestOptions).then(handleResponse)
.then((response)=> {
const file = new Blob([response], { type: "application/pdf" });
//Build a URL from the file
const fileURL = URL.createObjectURL(file);
//Open the URL on new Window
const pdfWindow = window.open();
pdfWindow.location.href = fileURL;
})
.catch((error) => {
console.log(error);
});
}
Hi I have a backend which receive a request with a picture and storage, I try it with postman and with the code below and works perfectly
var axios = require('axios')
var FormData = require('form-data')
var fs = require('fs')
var data = new FormData()
data.append('file', fs.createReadStream('index.png'))
console.log('HEADERS')
console.log(data.getHeaders())
let config = {
method: 'post',
url: 'http://localhost:5013/v1/business/honda/widget/test/',
headers: {
...data.getHeaders(),
},
data: data,
}
The problem is in my vue app I try to do it with the next code, I have 2 buttons with one load the image and the other to send it.
In the back end I have the follow error when try to pick 'file'
http: no such file
let imageData
//send the image to backend
function funtest() {
console.log('image')
const formData = new FormData()
const url = 'http://localhost:5013/v1/business/honda/widget/test/'
formData.append('file', imageData)
let config = {
method: 'post',
url: url,
headers: {
'Content-type': 'multipart/form-data',
},
data: formData,
}
axios(config)
.then((response) => {
console.log('RESPONSE')
console.log(response)
})
.catch((error) => {
console.log('ERROR')
console.log(error)
})
}
//function to read the image
function onImage(data) {
const reader = new FileReader()
reader.onload = (e) => {
imageData = e.target.result
console.log('imagen')
}
reader.readAsDataURL(data.target.files[0])
}
I think it's probably not reading the path to index.png file correctly here, fs.createReadStream('index.png')
Consider using path like this
const path = require('path');
const filePath = path.join(__dirname, 'index.png');
data.append('file', fs.createReadStream(filePath))
NB: This is just a quick and dirty suggestion, and it's not guaranteed to work but it's definitely worth a shot
Trying to download excel (.xlsx) file from my restAPI.
This is my code -
let headers = new Headers();
headers.append('Content-Type', 'application/vnd.openxmlformats');
this.http
.get(
`${pathToExcel}`,
{ headers: headers, responseType: ResponseContentType.Blob }
)
.subscribe((res: any) => {
let blob = new Blob([res._body], { type: 'application/vnd.openxmlformats' });
let myUrl = document.createElement('a');
myUrl.href = window.URL.createObjectURL(blob);
myUrl.download = 'Log.xlsx';
let event = document.createEvent('MouseEvent');
event.initEvent('click', true, true);
myUrl.dispatchEvent(event);
});
The file is downloaded but it's empty.
What am I missing?