【发布时间】:2011-07-07 22:03:42
【问题描述】:
在我们的网站中,我们嵌入了 PDF,我们希望确保当用户单击 PDF 中的链接时,它会在新的选项卡或窗口中打开。我们无法控制 PDF,因此我们无法对链接本身做任何事情。
是否可以通过某种方式拦截请求,例如使用 onbeforeunload,并强制新页面在单独的窗口中打开?
【问题讨论】:
标签: javascript pdf hyperlink
在我们的网站中,我们嵌入了 PDF,我们希望确保当用户单击 PDF 中的链接时,它会在新的选项卡或窗口中打开。我们无法控制 PDF,因此我们无法对链接本身做任何事情。
是否可以通过某种方式拦截请求,例如使用 onbeforeunload,并强制新页面在单独的窗口中打开?
【问题讨论】:
标签: javascript pdf hyperlink
这是否有兴趣:JS to open pdf's in new window?我假设您至少可以将 JavaScript 添加到页面。您不必修改 PDF 本身以便在新窗口中打开它们,即使您可能无法修改 url 本身,您也应该可以在页面上以任何您想要的方式打开这些链接。还是我完全误解了你的问题? :)
【讨论】:
不,抱歉,没有办法做到这一点。
这是设计使然。
如果有可能,这将是一个重大的安全漏洞。
【讨论】:
根据Aaron Digulla's answer,如果不修改 PDF 阅读器,您实际上无法做到这一点。对不起!
我认为如果不更改 Acrobat Reader 就无法做到这一点......我建议......其他一些不使用“单一文档”用户界面的 PDF 阅读器。 [Foxit Reader] 使用标签,可以显示多个 PDF 文档。
【讨论】:
您可以操作 PDF 文档中的链接以运行 javascript 在新窗口/选项卡中打开链接。以下是我使用 C# 和 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());
}
我从这个答案中得到了大部分代码:https://stackoverflow.com/a/8141831/596758
【讨论】: