Axios xlsx file download issue - vue.js

I try to download *.xlsx file in Vue by using Axios get request, however response that i get from GET is not what i expected, what i am trying to do:
on frontend in OnClick method:
const response = await this._fileService.getFileAsBlob(fileName);
const downloadBlob = new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;' })
virtualLink.href = URL.createObjectURL(downloadBlob);
virtualLink.download = file.fileName?? 'file';
virtualLink.click();
next the getFileAsBlob call
public getFileAsBlob(fileName: string): Promise<AxiosResponse<Blob>> {
return this._http.get<Blob>(`API_URL`, {
responseType: 'arraybuffer',
headers: {
"content-type": "application/octet-stream"
}
});
}
Now my concerns:
First, orginal file byte array is: byte[11524]
but in axios response.data this file is ArrayBuffer(15370) (disclaimer here, i've checked respone in backend, everything is working fine, at the last step backend is returning proper byte array)
Second, as i debugged this response, i've noticed, that although i set "content-type": "application/octet-stream" in response i get "application/json, text/plain, */*", what can be cause of it?
As a result, downloaded file is corrupted and cannot be opened by Excel, can somebody point me where am i having a flaw in logic?

Related

NPM Axios > 1.2.0 Library returning some improper response

I am using Axios library to retrieve Auth0 access tokens.
const { data, status, statusText } = await axios.post( https:auth0.url,
body,
{ headers: { "content-type": "application/x-www-form-urlencoded" } });
`
The issue i have is when i am using Axios 1.1.3 to retrieve access-tokens from Auth0 its giving me a proper response.
But when i update the library to 1.2.0 and higher everything breaks. I am getting a response for the same code as raw data
/#����W�{��bhu�E
:U�ȦG>SQ��6�y:90��w>B��� f�4:cA�P��V/����)��v%�_P�ɳ���ꑄ=lb���-F��zh�^X
��N�ˠ��G�
o����W(�Žx>�͔{�5*�������I������`�
���fA\��x~KS[
j��p�Ӌ<���u�qog�.)0G�FI/��R��OԽ�sm�ԝ{X�vV��s$i���2p`� �h�x_Ц��Z�u�9�X�d���B+P���l �m�h�Y��2���ԙ2
��Wx0K
� �Y2IX�d�����P�֎NЂu�qo���f".AJ��+���K枖0�
The stranger part is when i try to use the same code to get the result of an open source api.
const results = await axios.post("www.7timer.info/bin/api.pl?lon=113.17&lat=23.09&product=astro&output=json",
{ headers: { "content-type": "application/x-www-form-urlencoded" } });
I am getting a correct response.
I believe i am only getting this response when i am receiving a token from Auth0. Atleast in my use case
The error i am receiving when i call Auth0 to get tokens is
cause: Error: unexpected end of file
at BrotliDecoder.zlibOnError [as onerror] (node:zlib:189:17) {
errno: -5,
code: 'Z_BUF_ERROR'
}
Is anyone else facing the same issue?
bench-vue Thank you for your sample code. I had to add 'Accept-Encoding' in the request header to receive the tokens. Thank you for your help

Axios prepending content to start of file making it unreadable

I am trying to upload a file to an s3 presigned using axios from an expo managed mobile app FE. I have found that the following code works perfectly:
const file = await fetch(fileRef.uri);
const blob = await file.blob();
await fetch(uploadUrl, { method: 'PUT', body: blob });
here fileRef is an object like:
Object {
"height": 1920,
"uri": "file:///....jpg",
"width": 1080,
}
and uploadUrl is a presignedURL
I want to port this over to axios to take advantage of the onUploadProgress event. I've written the following:
const body = new FormData()
body.append('file', fileRef)
await axios.put(uploadUrl, body);
This uploads the file, however it prepends additional information to the start of the file that makes it so the image or video uploaded is not readable. The information it prepends looks like:
--9V.XUQuQ1DIG8HFMzJO-veI4JbmI7j_WawYPxtMUG2NhK_7eGnlL.kVNSXyH_sAQ2897mg^M
content-disposition: form-data; name="file"^M
content-type: image/jpeg^M
^M
I found that if i delete these lines, the file can now be opened (ex. by Quicktime).
I'd like to know how i can not have this information added to the start of the file?

Upload a file to an IPFS node from Google Apps Script

I'm trying to upload a file to an IPFS node using Google Apps Script (GAS) without success.
However, I was able to upload a file successfully using Postman. Unfortunately Postman only gives back the source code snippet closest to GAS as a JavaScript - Fetch code, which is not working as is in GAS.
In GAS, the authentication part is working and I know that because if I'm changing the bearer token, then I'm getting invalid credentials error instead of "Invalid request format".
Test code attached where I'm getting the "Invalid request format" error from the server.
For testing purpose, the file which needs to be uploaded, could be created on the fly with the script, but has to be one from Google Drive eventually.
function test() {
let myHeaders = {'Authorization': 'Bearer ...'};
let fileBlob = Utilities.newBlob('Hello!', 'text/plain', 'TestFile.txt');
let formdata = {'file': fileBlob,
'pinataMetadata': {'name': 'TestFileNewName.txt','keyvalues': {'MetaData1': 'Test1', 'MetaData2': 'Test2'}},
'pinataOptions': {'cidVersion': 0}};
let requestOptions = {
method: 'post',
headers: myHeaders,
papyload: formdata,
muteHttpExceptions: true
};
let url = "https://api.pinata.cloud/pinning/pinFileToIPFS";
let response = UrlFetchApp.fetch(url, requestOptions);
let responeText = JSON.parse(response.getContentText());
Logger.log(responeText);
}
If your access token of Bearer ... is the valid value for using the API, how about the following modification? From the official document, I thought that in the case of your formdata, the values of pinataMetadata and pinataOptions might be required to be the string type.
From:
let formdata = {'file': fileBlob,
'pinataMetadata': {'name': 'TestFileNewName.txt','keyvalues': {'MetaData1': 'Test1', 'MetaData2': 'Test2'}},
'pinataOptions': {'cidVersion': 0}};
To:
let formdata = {
'file': fileBlob,
'pinataMetadata': JSON.stringify({ 'name': 'TestFileNewName.txt', 'keyvalues': { 'MetaData1': 'Test1', 'MetaData2': 'Test2' } }),
'pinataOptions': JSON.stringify({ 'cidVersion': 0 })
};
And also, please modify papyload: formdata, to payload: formdata,. This has already been mentioned by
TheMaster's comment.
References:
Pin File
fetch(url, params)

Using AXIOS to POST to external server API to retrieve SSOID

In short: Here is some Python code posting to Betfair API. I would like to use Axios to do the same thing.
resp = requests.post('https://identitysso-cert.betfair.com/api/certlogin',
data=payload, cert=('TestApp.crt', 'client-2048.key'), headers=headers)
I'm reading through AXIOS docs, and am curious how to apply the cert=('TestApp.crt', 'cient-2048.key') field.
In detail: Currently, I have this:
axios({
method: "POST",
headers: headers,
url: "https://identitysso-cert.betfair.com/api/certlogin",
data: payload,
});
Would I use the form-data library replacing cert=('TestApp.crt', 'cient-2048.key') with form<FormData>
const FormData = require("form-data");
const form = new FormData();
form.append("my_field", "my value");
form.append("my_buffer", new Buffer(10));
form.append("my_file", fs.createReadStream("/foo/bar.jpg"));
axios.post("https://example.com", form, { headers: form.getHeaders() });
EDIT:
Scrapped the FormData route, and am using HTTPS for node js.
I add this along with the options I provide to Axios.
const httpsAgent = new https.Agent({
cert: fs.readFileSync("certificat.crt"),
ca: fs.readFileSync("key.pem"),
});
I in turn get this error:
Error: "Error: SSL Error: SELF_SIGNED_CERT_IN_CHAIN"
Digging a little deeper,
The error SELF_SIGNED_CERT_IN_CHAIN means that you cannot use self-signed certificates.
I ended up using Python to accomplish what I needed.

Vue Resource Cross-site HTTP request

Normally, when I make a jQuery request to a non-local server, it applies Cross-site HTTP request rules and initially sends an OPTIONS request to verify the existence of an endpoint and then it sends the request, i.e.
GET to domain.tld/api/get/user/data/user_id
jQuery works fine, however I would like to use Vue Resource to deal with requests. In my network log, I see only the actual request being made (no OPTIONS request initially), and no data is being received.
Anybody has an idea how to solve this?
Sample Code:
var options = {
headers: {
'Authorization': 'Bearer xxx'
}
};
this.$http.get(config.api.base_url + 'open/cities',[options])
.then(function(response){
console.log('new request');
vm.cities = response;
}, function(error){
console.log('error in .js:');
console.log(error);
});
jquery-request
Solution:
As #Anton mentioned, it's not necessary to have both requests (environment negligible). Not sure what I have changed to make it work, but the request gave me an error. It consisted in setting the headers correctly. Headers should not be passed as options but as a property of http:
this.$http({
root: config.api.base_url + 'open/cities', // url, endpoint
method: 'GET',
headers: {
'Authorization': 'Bearer xxx'
}
}).then(function(response){
console.log('new request');
vm.cities = response;
}, function(error){
console.log('error in .js:');
console.log(error);
});
Thank you guys, it was a team effort :)
Is it a requirement that an additional OPTIONS request is being made? I have created a small (32 LOC) example which works fine and retrieves the data:
https://jsfiddle.net/ct372m7x/2/
As you can see, the data is being loaded from a non-local server. The example is located on jsfiddle.net and the request is made to httpbin.org - this leads to CORS being applied (you can see the Access-Control-Allow-Origin header in the screenshot below).
What you also see is that only the GET request has been executed, no OPTIONS before that.