- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-23-2017 03:37 AM
Hello,
I'm trying to send a PDF file to ServiceNow through the Rest API but all the sent PDF are blank when opened at ServiceNow side.
Here are the details of what I'm trying to do.
From my tools on the web browser, I download the PDF from the server and I obtain it as the base64 encoded string.
The API I'm contacting is : Attachement API - POST /now/attachement/file
What I tried to do :
var data = new FormData();
data.append(file_name, atob(file64));// decode from base64 to string
//Start request
$.ajax(
{
url: base_url + "/api/nom/attachment/file?table_name=incident&table_sys_id=" + sys_id + "&file_name=" + file_name,
type: "POST",
dataType: "json",
data: data,
beforeSend: function(xhr)
{
xhr.setRequestHeader("Authorization", "Bearer " + token);
xhr.setRequestHeader("Content-Type", "application/pdf");
},
success: function(data)
{
alert("Success");
},
error: function(result)
{
alert("Error : " + result);
},
});
That's more or less the code I'm using to send the file to ServiceNow and I got a positive answer on that one : 201 Created.
But when my interlocutor tries to open the file, the PDF is completely blank and on closure the PDF reader ask to save the file. After saving, the document is still blank.
Opening the file with a text editor shows Boundary limits, as if the server didn't removed them after receiving the file.
------WebKitFormBoundaryIffgXSqZrXwI7Ysx
Content-Disposition: form-data; name="Test1.pdf"
I also tried to send the file without a form data.
var data = atob(file64));// decode from base64 to string
//Start request
$.ajax(
{
url: base_url + "/api/nom/attachment/file?table_name=incident&table_sys_id=" + sys_id + "&file_name=" + file_name,
type: "POST",
dataType: "json",
data: data,
beforeSend: function(xhr)
{
xhr.setRequestHeader("Authorization", "Bearer " + token);
xhr.setRequestHeader("Content-Type", "application/pdf");
},
success: function(data)
{
alert("Success");
},
error: function(result)
{
});
alert("Error : " + result);
},
});
But I got the same result, PDF blank asking for save. This time without Bondary limits (logical as didn't use FormData() ) ...
I also tried to send the base64 encoded string specifying in the HTTP request that it was encoded.
xhr.setRequestHeader("Content-Type", "application/pdf; base64");
I got less success this time, as the string wasn't decoded by the server and still saved as a PDF.
Am I doing something wrong in sending the file to ServiceNow ? Does anyone have an hint on how to solve this ?
Regards,
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-27-2017 01:45 AM
Hello,
I more or less founded an answer to my problem. As PDF files seem to be binary files, there is a specific way to handle them, which I knew nothing about.
To successfully send a pdf files with ajax, you need to use a BLOB (Binary Large OBject), as described here : Sending and Receiving Binary Data - Web APIs | MDN (part Sending binary data)
More info on those BLOB can be found here : Blob() - Web APIs | MDN
The solution to my problem come from this post : Creating a Blob from a base64 string in JavaScript - Stack Overflow
For those who might need it, here is the code I implemented :
var file64 = "";// get base64 encoded file
// Start Request
var xhr = new XMLHttpRequest();
xhr.open("POST", base_url + "/api/now/attachment/file?table_name=incident&table_sys_id=" + sys_id + "&file_name=" + file_name);
xhr.setRequestHeader("Content-Type", "application/pdf");
xhr.setRequestHeader("Authorization", "Bearer " + token);
xhr.onreadystatechange = function(response)
{
if (this.readyState === XMLHttpRequest.DONE)// Get the Http status from ServiceNow's server
{
alert(this.status + " " + this.statusText);
}
}
// Transform the base64 encoded file into a Blob
var byteCharacters = atob(file64);
var byteArrays= [];
var sliceSize = 512;
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize)
{
var slice = byteCharacters.slice(offset, offset + sliceSize);
var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++)
{
byteNumbers[i] = slice.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
var blob = new Blob(byteArrays, {type: "application/pdf",});
xhr.send(blob);// Add the blob to the request and send it
PDF files are successfully sent to, saved on server and read by users.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-26-2017 12:50 PM
Hello Francois,
Is the PDF file in the binary format? Did you decode the file into Binary?
Jeff
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-27-2017 01:08 AM
Hello Jeffrey,
If I recall correctly, PDF files are binary files already, so I'm not sure I understand what you mean by decoding the file into binary ...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-27-2017 01:45 AM
Hello,
I more or less founded an answer to my problem. As PDF files seem to be binary files, there is a specific way to handle them, which I knew nothing about.
To successfully send a pdf files with ajax, you need to use a BLOB (Binary Large OBject), as described here : Sending and Receiving Binary Data - Web APIs | MDN (part Sending binary data)
More info on those BLOB can be found here : Blob() - Web APIs | MDN
The solution to my problem come from this post : Creating a Blob from a base64 string in JavaScript - Stack Overflow
For those who might need it, here is the code I implemented :
var file64 = "";// get base64 encoded file
// Start Request
var xhr = new XMLHttpRequest();
xhr.open("POST", base_url + "/api/now/attachment/file?table_name=incident&table_sys_id=" + sys_id + "&file_name=" + file_name);
xhr.setRequestHeader("Content-Type", "application/pdf");
xhr.setRequestHeader("Authorization", "Bearer " + token);
xhr.onreadystatechange = function(response)
{
if (this.readyState === XMLHttpRequest.DONE)// Get the Http status from ServiceNow's server
{
alert(this.status + " " + this.statusText);
}
}
// Transform the base64 encoded file into a Blob
var byteCharacters = atob(file64);
var byteArrays= [];
var sliceSize = 512;
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize)
{
var slice = byteCharacters.slice(offset, offset + sliceSize);
var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++)
{
byteNumbers[i] = slice.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
var blob = new Blob(byteArrays, {type: "application/pdf",});
xhr.send(blob);// Add the blob to the request and send it
PDF files are successfully sent to, saved on server and read by users.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎01-05-2020 10:15 AM
Hi ,
How can we convert Base64 string to Blob through servicenow script ? Uint8Array and ArrayBuffer , Blob key words ( functionality of ES6) not supported while running through servicenow script, Does it work for you ?