URL.createObjectURL(blob); - javascript

I am creating a PDF and opening in a new browser. My issue is word 'blob:' is getting appended to the URL
blob:http://localhost:3000/a0b859c9-57a0-40b7-a60f-9d2a72ab3c14
and I would like to be 'http://localhost:3000/a0b859c9-57a0-40b7-a60f-9d2a72ab3c14'
Is there a way I could achieve this ? My code is below
const blob = new Blob([response.data], {type : 'application/pdf'});
var pdfFileUrl = URL.createObjectURL(blob);
window.open(pdfFileUrl);
URL.revokeObjectURL(pdfFileUrl);
update:
I tried below code as well. It also gives the same results.
''
const xhr = new XMLHttpRequest();
//Send the proper header information along with the request
// listen for `onload` event
xhr.onload = () => {
// process response
if (xhr.status == 200) {
// parse JSON data
// console.log( "Response Received")
// var pdfurl = URL.createObjectURL(xhr.response) ;
console.log(xhr.response)
window.open(URL.createObjectURL(xhr.response));
} else {
console.log(" In Error block")
console.error('Error!');
}
};
// create a `GET` request
xhr.open('POST', url);
xhr.responseType = 'blob'
xhr.setRequestHeader('Content-Type', 'application/json');
// send request
xhr.send(JSON.stringify(payload));''

Related

I am trying to make a post request using javascript to my fast api app. But it is giving error INFO. 422 Unprocessable Entity

// variables for getting Original URL
const form2 = document.getElementById("form2");
const resultContainer2 = document.querySelector(".result__container2");
const longUrl = document.querySelector(".longurl");
//for decoding the url (Retrieving Original URL)
form2.addEventListener("submit", (e) => {
e.preventDefault();
var formData = new FormData();
formData.append("shortUrl", e.target.shortUrl.value);
formData.append("customCode", e.target.shortUrl.value);
let data = {}
for(let pair of formData.entries()) {
data[pair[0]] = pair[1]
}
console.log(data)
let xhr = new XMLHttpRequest();
xhr.open("POST", "/api/v2/original", true);
// Set the request header
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function() {
if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
console.log("Done")
}
}
//Displaying the Original long URL
xhr.onload = function () {
const response = JSON.parse(this.responseText);
console.log(this.status);
console.log(response);
if(this.status ==200) {
resultContainer2.style.display = "flex";
longUrl.innerHTML = `ORIGINAL LONG URL :- <a href=${response.longUrl}>${response.longUrl}</a>`
}
else {
alert(`An error occurred, ${response.detail}`)
}
};
//using JSON for transfering data in between, as per task requirement (JSON Object to JSON string)
xhr.send(JSON.stringify(data));
})

How to set multiple headers data with XMLHttpRequest in async mode?

My api call requires me to pass the api key in the headers, but I'm getting error back from the api service {"error":"2424452","message":"Invalid Api Key"}
I know my api key is valid as I can make the same api call in Python just fine, example:
req = requests.Session()
req.headers.update({'x-api-key': 'my-api-key', 'X-Product': 'my-product-name'})
req.get(url)
But in javscript, the same call errors out. I believe I'm not setting the headers correctly or something?
var req = new XMLHttpRequest();
req.onreadystatechange=handleStateChange;
req.open("GET", "url", true);
req.setRequestHeader("Host", "api.domain.com", "x-api-key", "my-api-key", "X-Product", "my-product-name");
req.send();
This XMLHttpRequest is not a browser call, rather in an application that support XMLHttpRequest.
setRequestHeader sets one header and takes two arguments (the name and the value).
If you want to set multiple headers, then call setRequestHeader multiple times. Don't add extra arguments to the first call.
In case you don't want to set multiple headers explicitly you can use
function setHeaders(headers){
for(let key in headers){
xhr.setRequestHeader(key, headers[key])
}
}
setHeaders({"Host":"api.domain.com","X-Requested-With":"XMLHttpRequest","contentType":"application/json"})
downloadReportFile(id, query): Observable<Object[]> {
var url = `${environment.baseUrl}report?report_name=${id}${query}`;
return Observable.create(observer => {
let xhr = new XMLHttpRequest();
xhr.open('GET', `${url}`, true);
xhr.setRequestHeader(environment.AUTH_TOKEN_HEADER_KEY, 'Bearer '+
localStorage.getItem(environment.AUTH_TOKEN_STORE_KEY));
xhr.responseType = 'blob';
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
let filename = "Claim_Report.csv"
var contentType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
var blob = new Blob([xhr.response], { type: "text/plain;charset=utf-8" });
if (typeof window.navigator.msSaveBlob !== 'undefined') {
window.navigator.msSaveBlob(blob, filename);
return;
}
const blobURL = window.URL.createObjectURL(blob);
const tempLink = document.createElement('a');
tempLink.style.display = 'none';
tempLink.href = blobURL;
tempLink.setAttribute('download', filename);
if (typeof tempLink.download === 'undefined') {
tempLink.setAttribute('target', '_blank');
}
document.body.appendChild(tempLink);
tempLink.click();
document.body.removeChild(tempLink);
setTimeout(() => {
// For Firefox it is necessary to delay revoking the ObjectURL
window.URL.revokeObjectURL(blobURL);
}, 100);
} else {
observer.error(xhr.response);
}
}
}
xhr.send();
});
}

InboxSDK - Unable to attachFiles through composeView object

I am trying to attach an attachment through the composeView object using Inboxsdk. I obtain a blob object from a remote url using the following code.
// FUNCTION TO OPEN A NEW COMPOSE BOX ONCE THE ATTACHMENT BLOB IS OBTAINED FROM REMOTE URL.
function openComposeBox(sdk, blob){
handler = sdk.Compose.registerComposeViewHandler(function(composeView){
if(blob != null){
composeView.attachFiles([blob]);
composeView.setSubject("Testing");
}
});
}
// FETCHING ATTACHMENT FILE FROM REMOTE URL
var file_btn_url = "https://api.hummingbill.com/system/invoices/invoice_files/000/033/393/original/abracadabra.txt";
var file_name = file_btn_url.split("/");
file_name = file_name[file_name.length-1];
file_type = /[^.]+$/.exec(file_name);
var blob = null;
var xhr = new XMLHttpRequest();
xhr.open("GET", file_btn_url);
xhr.responseType = "blob";
xhr.onload = function()
{
blob = xhr.response;
// blob.lastModifiedDate = new Date(); // Since it's not necessary to have it assigned, hence commented.
blob.name = file_name;
console.log(blob);
openComposeBox(sdk, blob);
}
xhr.send();
It shows an Attachment Failed error.
Although I have the correct format of blob object as required as per the documentation.
As per the documentation, I have set the filename for the blob, and passed it in an array to attachFiles function. Can you please look into it and let me know what am I missing?
Posting the solution. The code remains same as in the question, with a slight variation, wherein we convert the blob to a file, in order to make it work.
//... Same as the code in the question
// Fetching attachment file from remote url
var file_btn_url = "https://api.hummingbill.com/system/invoices/invoice_files/000/033/393/original/abracadabra.txt";
var file_name = file_btn_url.split("/");
file_name = file_name[file_name.length-1];
file_type = /[^.]+$/.exec(file_name);
var blob = null;
var xhr = new XMLHttpRequest();
xhr.open("GET", file_btn_url);
xhr.responseType = "blob";
xhr.onload = function()
{
// Solution: Convert the obtained blob to a file
// Pass the file to openComposeBox
blob = new Blob([xhr.response], { type: xhr.responseType });
var file = new File([blob], file_name);
blob.name = file_name;
openComposeBox(sdk, file);
}
xhr.send();
Hope this helps. Cheers!

handling csv response in backbonejs

I am posting some data to server through Backbone.js and server sends a csv file as response. As Backbone.js handles only json format can some body tell me how to handle this case, so that i would be able to download the csv file gracefully.
object = {};
object.c1 = formObj.c1
hash = {
success: function(model, response, options) {
},
error: function(model, response, options) {
return console.log(response);
}
};
model = new P.models.mine(object);
model.doSomething(object, hash);
It always comes to error part.
The ideal way to handle this would be to change your back end code to return JSON, or create another route that returns JSON. Since you are asking this question I'm assuming that isn't an option for you.
Basically you are going to have to parse the CSV on the client side:
https://stackoverflow.com/a/1293163/944006 - Should get you started.
If you are asking to download a csv file, then just pointing the browser at the location should prompt the user for download. You cannot prompt a file download through ajax(for good reason), but there are ways to tiptoe around this limitation:
https://stackoverflow.com/a/9970672/944006
You could also use plain javascript rather than Backbone.js. Believe me this is the best way.
Here is some code:
var xhr = new XMLHttpRequest();
xhr.open('POST', Urls.download, true);
xhr.responseType = 'blob';
xhr.setRequestHeader("Authorization", "Bearer " + access_token);
xhr.setRequestHeader('Content-type', 'application/json; charset=utf-8');
xhr.onload = function (e) {
if (this.status == 200) {
var blob = new Blob([this.response], { type: 'application/vnd.ms-excel' });
var downloadUrl = URL.createObjectURL(blob);
var a = document.createElement("a");
a.id = "a" + new Date().getTime();
a.setAttribute("data-bypass", "");
a.href = downloadUrl;
a.download = "list_" + new Date().getTime() + ".xlsx";
document.body.appendChild(a);
a.click();
} else {
alert('Unable to download excel.')
}
};
xhr.send(JSON.stringify(this.obj));

Download Binary Data as a File Via Javascript

I'm making an ajax call to an API that returns binary data. I'm wondering if its possible to take that binary data and display it for the client in a new window? This is what I'm doing right now. The problem is, the document opens up, but its completely blank.
$.ajax({
type: "POST",
url: apiURL,
data: xmlRequest,
complete: function(xhr, status) {
var bb = new window.WebKitBlobBuilder();
// Append the binary data to the blob
bb.append(xhr.responseText);
var blobURL = window.webkitURL.createObjectURL(bb.getBlob('application/pdf'));
window.open(blobURL);
}
});
Any ideas?
Okay, I figured it out. I had to specify the responseType as 'array buffer':
function downloadPDF() {
var xhr = new XMLHttpRequest();
xhr.open('POST', API_URL, true);
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
if (this.status == 200) {
var bb = new window.WebKitBlobBuilder();
bb.append(this.response); // Note: not xhr.responseText
var blob = bb.getBlob('application/pdf');
var blobURL = window.webkitURL.createObjectURL(blob);
window.open(blobURL);
}
};
xhr.send(createRequest());
}

Categories

Resources