
As navigation through pages in PDF viewer for ENADOC is a hectic and time-consuming , as navigating directly to a page number is not possible , we had to fetch the stream of data through API and present it inside Iframe.
While working on the mentioned task, I saw the following behaviors
- Pdf inside Iframe Worked well for small sized files (with less number of pages)
- For large number of pages, blank canvas was seen inside Iframe.
After hours of googling and digging into the issue, I found out that Iframe have limitation on the size of src.
Previously, base64 string was sent as JSON response to AJAX request and the same was set as Iframe source, which had the mentioned issues.
public ActionResult GetAttachmentData(int attachmentId)
{
// method implementation goes here
var byteArray= fetchByteArrayFromEnadoc(attachmentId);
var base64String = Convert.ToBase64String(byteArray);
base64String = string.Format($"data:application/pdf;base64,{{0}}", base64String);
return Json(base64String);
}
and in client-side,
$.ajax({
url: url,
data: {attachmentId: id },
success: function (response) {
var iframe = `<iframe width='100%' height='100%' src='${response}'></iframe>`;
var x = window.open();
x.document.open();
x.document.write(iframe);
x.document.close();
}
})
This didn't work for large pdf files.
As a workaround, instead of passing the large base64 string as iframe src , Url was set as the source of iframe and the url returned the pdf as response , which was rendered inside Iframe.
The new implementation looked like below
public class AttachmentController : Controller
{
public ActionResult GetPdfBase64String(string Key)
{
byte[] data=null;
lock(new object())
{
if (_PdfUrlKeys.ContainsKey(Key))
{
data = _PdfUrlKeys[Key];
_PdfUrlKeys.Remove(Key);
}
}
return File(data, "application/pdf");
}
public ActionResult GetAttachmentData(int attachmentId)
{
//method implementation goes here
var byteArray= fetchByteArrayFromEnadoc(attachmentId);
string random=string.Empty;
lock (new object())
{
random = Guid.NewGuid().ToString();
while (_PdfUrlKeys.ContainsKey(random))
{
random = Guid.NewGuid().ToString();
}
_PdfUrlKeys.Add(random, byteArray);
}
return Json(random);
}
}
and in client-side, the key returned from GetAttachmentData method is used to download PDF into Iframe canvas calling the endpoint GetPdfBase64String.
$.ajax({
url: url,
data: {attachmentId: id },
success: function (response) {
let pdfSrc= `${window.location.origin}/attachment/GetPdfBase64String?Key=${response}`;
var iframe = `<iframe width='100%' height='100%' src='${pdfSrc}'></iframe>`
var x = window.open();
x.document.open();
x.document.write(iframe);
x.document.close();
}
})
Thanks for reading!!