In our web site 开发者_JS百科we have embedded PDFs, and we would like to make sure that when the user clicks a link inside the PDF, it opens in a new tab or window. We have no control over the PDFs so we cannot do anything with the links themselves.
Is it possible to intercept the request in some way, for example with onbeforeunload, and force the new page to open in a separate window?
No sorry, there is no way of doing this.
This is by design.
If it was possible it would be a major security breach.
You can manipulate the links inside the PDF document to run a javascript to open links in a new window/tab. Heres how I did it with C#
and iTextSharp
public static MemoryStream OpenLinksInNewWindow(MemoryStream mySource)
{
PdfReader myReader = new PdfReader(mySource);
int intPageCount = myReader.NumberOfPages;
PdfDictionary myPageDictionary = default(PdfDictionary);
PdfArray myLinks = default(PdfArray);
//Loop through each page
for (int i = 1; i <= intPageCount; i++)
{
//Get the current page
myPageDictionary = myReader.GetPageN(i);
//Get all of the annotations for the current page
myLinks = myPageDictionary.GetAsArray(PdfName.ANNOTS);
//Make sure we have something
if ((myLinks == null) || (myLinks.Length == 0))
continue;
//Loop through each annotation
foreach (PdfObject myLink in myLinks.ArrayList)
{
//Convert the itext-specific object as a generic PDF object
PdfDictionary myLinkDictionary = (PdfDictionary)PdfReader.GetPdfObject(myLink);
//Make sure this annotation has a link
if (!myLinkDictionary.Get(PdfName.SUBTYPE).Equals(PdfName.LINK))
continue;
//Make sure this annotation has an ACTION
if (myLinkDictionary.Get(PdfName.A) == null)
continue;
//Get the ACTION for the current annotation
PdfDictionary myLinkAction = (PdfDictionary)myLinkDictionary.Get(PdfName.A);
//Test if it is a URI action
if (myLinkAction.Get(PdfName.S).Equals(PdfName.URI))
{
//Replace the link to run a javascript function instead
myLinkAction.Remove(PdfName.F);
myLinkAction.Remove(PdfName.WIN);
myLinkAction.Put(PdfName.S, PdfName.JAVASCRIPT);
myLinkAction.Put(PdfName.JS, new PdfString(String.Format("OpenLink('{0}');", myLinkAction.Get(PdfName.URI))));
}
}
}
//Next we create a new document add import each page from the reader above
MemoryStream myMemoryStream = new MemoryStream();
using (Document myDocument = new Document())
{
using (PdfCopy myWriter = new PdfCopy(myDocument, myMemoryStream))
{
myDocument.Open();
for (int i = 1; i <= myReader.NumberOfPages; i++)
{
myWriter.AddPage(myWriter.GetImportedPage(myReader, i));
}
// Insert JavaScript function to open link
string jsText = "function OpenLink(uri) { app.launchURL(uri, true); }";
PdfAction js = PdfAction.JavaScript(jsText, myWriter);
myWriter.AddJavaScript(js);
myDocument.Close();
}
}
return new MemoryStream(myMemoryStream.GetBuffer());
}
I got most code from this answer: https://stackoverflow.com/a/8141831/596758
According to Aaron Digulla's answer, you can't actually do this without modifying the PDF reader. Sorry!
I think you can't do this without changing Acrobat Reader... I suggest ... some other PDF reader which doesn't use a "single document" UI. [Foxit Reader] uses tabs and can display several PDF documents.
Could this be of interest: JS to open pdf's in new window? I'm assuming that you can at least add JavaScript to the page. You shouldn't have to modify the PDF's themselves in order to open them in a new window, and even though you might not be able to modify the url's themselves you should be free to open those links in any fashion you want on your page. Or am I completely misunderstanding your question? :)
精彩评论