Javascript 当在IE9对象元素中查看时,如何从pdf中向主机发送“postMessage”

Javascript 当在IE9对象元素中查看时,如何从pdf中向主机发送“postMessage”,javascript,asp.net-mvc,pdf,internet-explorer-9,itextsharp,Javascript,Asp.net Mvc,Pdf,Internet Explorer 9,Itextsharp,我试图用PDF做一个小型PoC,但遇到了一个问题。我想把一条信息发布到PDF,并让PDF将一条信息发布到浏览器 deets: 我正在IE9中的对象元素中查看PDF。我使用itextsharp在服务器上预先填充pdf模板,注入一些应用程序级javascript post消息和消息内容,然后通过filestreamresult将其提供给浏览器。我正在使用Reader10查看IE9中的PDF 工作原理: 到目前为止,除了在浏览器中发布消息的PDF外,其他一切都正常工作。我可以通过浏览器将消息发布到PD

我试图用PDF做一个小型PoC,但遇到了一个问题。我想把一条信息发布到PDF,并让PDF将一条信息发布到浏览器

deets:

我正在IE9中的对象元素中查看PDF。我使用itextsharp在服务器上预先填充pdf模板,注入一些应用程序级javascript post消息和消息内容,然后通过filestreamresult将其提供给浏览器。我正在使用Reader10查看IE9中的PDF

工作原理:

到目前为止,除了在浏览器中发布消息的PDF外,其他一切都正常工作。我可以通过浏览器将消息发布到PDF中,没有问题,所有字段都会根据需要进行预填充

什么不起作用:

当我尝试使用这个.hostContainer.postMessage[something,somethingmore]时,我会得到一个Acrobat Escript窗口,其中显示未定义hostContainer。我也尝试过使用event.target.hostContainer,但我得到的是event.target未定义。我不知道该做什么,任何见解都会非常有用

参考链接:

守则:

我的表单视图:

填写表格并将其发送到浏览器的方法:


好的,我已经解决了,当然有一些帮助。我在家里找到了钥匙。在分配消息处理程序之前,我需要等待对象加载。此外,我需要pdf javascript中的全局变量才能发布消息

Html/Javascript:这里的关键是loadListener函数

    @model WebModel.FormView
<object id="pdfFrame" style="width:100%;height: 100%;" data="@Url.Action("LoadForm")">No luck :(</object>
    <input id="buttonPost" type="button" value="post to pdf"/>
    <script type="text/javascript">
        var PDFObject = document.getElementById("pdfFrame");
        function loadListener() {
            if (typeof PDFObject.readyState === 'undefined') { // ready state only works for IE, which is good because we only need to do this for IE because IE sucks in the first place
                debugger;
                PDFObject.messageHandler = { onMessage: messageFunc };
                return;
            }
            if (PDFObject.readyState == 4) {
                debugger;
                PDFObject.messageHandler = { onMessage: messageFunc };
            } else {
                setTimeout(loadListener, 500);
            }
        }
        function messageFunc(data) {
            debugger;
            var messagedata = data;
            alert('finally!!');
        }

        function sendToPdf() {
            if(PDFObject!= null){
                PDFObject.postMessage(
                ["a", "b"]);
            }
        }

        $('#pdfFrame').ready(function() {
            loadListener();
            $('#buttonPost').on('click', function() {
                sendToPdf();
            });
        });

    </script>

您可能已经看到了这一点,但有些人正在讨论文档模式,并使用遗留类id属性,也许可以试一试。事实上,我只是遇到了这个问题。如何确定classid值应该是什么?类id是该线程中列出的内容,clsid:CA8A9780-280D-11CF-A24D-444553540000。实际上,您可以通过在HKCR\AcroPDF.PDF\CLSID下的Windows注册表中查找该GUID。该GUID在所有安装了Acrobat Reader的计算机中都很常见。好的,是的,很好,谢谢。我把它添加到我的object元素中,现在看起来是这样的:不走运:但它仍然不起作用。我终于让它起作用了,我将清理我的代码并很快发布一个答案。代码似乎有一个问题:我必须更改PDFObject.messageHandler={onMessage:messageFunc};到PDFObject.messageHandler={onMessage:messageFunc};否则,它就不适用于任何人me@Robert我不知道为什么会这样。您的代码将执行messageFunc并将结果设置为onMessage属性。。。这很奇怪。有隐藏的语法错误吗?@JasonWolczak:我同意你的看法。我认为它是有效的,因为它没有使用messageHandler机制。我的loadListener函数每500毫秒调用一次,如果我达到就绪状态,它将直接调用messageFunc。在我的案例中,可以删除printer.messageHandler={onMessage:…}。我得检查一下如何使它正常工作。
private static string GetCustomJavascript(string existingJavaScript)
    {
        const string newJs = 
        "this.disclosed = true; " +
        "if (this.external && this.hostContainer) { " +
            "function onMessageFunc( stringArray ) { " +
//                    "var name = this.myDoc.getField(personal.name); " +
//                    "var login = this.myDoc.getField(personal.loginname); " +
                    "try{" +
                        "app.alert(doc.xfa);" +
                        "console.println('Doc xfa value = ' + doc.xfa);" +
//                            "event.target.hostContainer.postMessage(['hello from pdf!']);" +
//                        "this.hostContainer.postMessage(['hello from pdf!']);"+
//                        "name.value = stringArray[0]; " +
//                        "login.value = stringArray[1]; " +
                    "} catch(e){ onErrorFunc(e); } " +
                "} " +
                "function onErrorFunc( e ) { " +
                    "console.show(); " +
                    "console.println(e.toString()); " +
                "} " +
                "try {" +
                    "if(!this.hostContainer.messageHandler) { " +
                        "this.hostContainer.messageHandler = new Object(); " +
                        "this.hostContainer.messageHandler.myDoc = this; " +
                        "this.hostContainer.messageHandler.onMessage = onMessageFunc; " +
                        "this.hostContainer.messageHandler.onError = onErrorFunc; " +
                        "this.hostContainer.messageHandler.onDisclose = function(){ return true; }; " +
                    "}" +
                "} catch(e){onErrorFunc(e);}" +
            "}";
            var jsToReturn = existingJavaScript + newJs;
            return jsToReturn;
        }
public MemoryStream GetFilledRequestForm(string fileDirectory, User user, FormView formView)
        {
            var pdfStream = new MemoryStream();
            var templateFilePath = GetRequestTypeTemplateFilePath(fileDirectory, _requestModule.FormTemplateFileName);
            var pdfReader = new PdfReader(templateFilePath);
//            pdfReader.RemoveUsageRights();
            var stamper = new PdfStamper(pdfReader, pdfStream);
            var formFields = GetFormFields(user, formView, pdfReader);
            foreach (var field in formFields.Where(f => f.Value != null))
            {
                stamper.AcroFields.SetField(field.Name, field.Value);
            }
            stamper.FormFlattening = false;
            var newJs =  GetCustomJavascript(stamper.Reader.JavaScript);
            stamper.AddJavaScript("newJs", newJs);
            stamper.Close();
            byte[] byteInfo = pdfStream.ToArray();
            var outputStream = new MemoryStream();
            outputStream.Write(byteInfo, 0, byteInfo.Length);
            outputStream.Position = 0;
            return outputStream;
        }
    @model WebModel.FormView
<object id="pdfFrame" style="width:100%;height: 100%;" data="@Url.Action("LoadForm")">No luck :(</object>
    <input id="buttonPost" type="button" value="post to pdf"/>
    <script type="text/javascript">
        var PDFObject = document.getElementById("pdfFrame");
        function loadListener() {
            if (typeof PDFObject.readyState === 'undefined') { // ready state only works for IE, which is good because we only need to do this for IE because IE sucks in the first place
                debugger;
                PDFObject.messageHandler = { onMessage: messageFunc };
                return;
            }
            if (PDFObject.readyState == 4) {
                debugger;
                PDFObject.messageHandler = { onMessage: messageFunc };
            } else {
                setTimeout(loadListener, 500);
            }
        }
        function messageFunc(data) {
            debugger;
            var messagedata = data;
            alert('finally!!');
        }

        function sendToPdf() {
            if(PDFObject!= null){
                PDFObject.postMessage(
                ["a", "b"]);
            }
        }

        $('#pdfFrame').ready(function() {
            loadListener();
            $('#buttonPost').on('click', function() {
                sendToPdf();
            });
        });

    </script>
private static string GetCustomJavascript(string existingJavaScript)
        {
            const string newJs = 
            "this.disclosed = true; " +
            "var appHostContainer = this.hostContainer;" + 
            "if (this.external && this.hostContainer) { " +
                "function onMessageFunc( stringArray ) { " +
//                    "var name = this.myDoc.getField(personal.name); " +
//                    "var login = this.myDoc.getField(personal.loginname); " +
                    "try{" +
                        "app.alert(stringArray);" +
                        "appHostContainer.postMessage(['hello from pdf!']);" +
//                        "name.value = stringArray[0]; " +
//                        "login.value = stringArray[1]; " +
                    "} catch(e){ onErrorFunc(e); } " +
                "} " +
                "function onErrorFunc( e ) { " +
                    "console.show(); " +
                    "console.println(e.toString()); " +
                "} " +
                "try {" +
                    "if(!this.hostContainer.messageHandler) { " +
                        "this.hostContainer.messageHandler = new Object(); " +
                        "this.hostContainer.messageHandler.myDoc = this; " +
                        "this.hostContainer.messageHandler.onMessage = onMessageFunc; " +
                        "this.hostContainer.messageHandler.onError = onErrorFunc; " +
                        "this.hostContainer.messageHandler.onDisclose = function(){ return true; }; " +
                    "}" +
                "} catch(e){onErrorFunc(e);}" +
            "}";
            var jsToReturn = existingJavaScript + newJs;
            return jsToReturn;
        }