Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/413.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 自定义错误XPage:浏览器能够在错误加载后加载并执行JS脚本链接或块_Javascript_Dojo_Xpages_Xpages Ssjs - Fatal编程技术网

Javascript 自定义错误XPage:浏览器能够在错误加载后加载并执行JS脚本链接或块

Javascript 自定义错误XPage:浏览器能够在错误加载后加载并执行JS脚本链接或块,javascript,dojo,xpages,xpages-ssjs,Javascript,Dojo,Xpages,Xpages Ssjs,形势 我使用的是一个自定义错误XPage,它高度依赖于。它工作得相当好,但我希望浏览器执行客户端JavaScript块(或从给定URL加载并运行JS文件)。如果我直接导航到自定义错误XPage,它会正确加载,但考虑到它如何从SSJS运行时错误重定向加载的性质,它似乎会加载任何试图在head标记中、body标记内加载脚本块的尝试。我尝试在正文中传递JS脚本标记(如下面的代码所示),尝试,尝试 浏览器视角 从浏览器的角度来看,在部分刷新期间调用SSJS的事件中遇到运行时错误后,被调用的xhr返回50

形势

我使用的是一个自定义错误XPage,它高度依赖于。它工作得相当好,但我希望浏览器执行客户端JavaScript块(或从给定URL加载并运行JS文件)。如果我直接导航到自定义错误XPage,它会正确加载,但考虑到它如何从SSJS运行时错误重定向加载的性质,它似乎会加载任何试图在head标记中、body标记内加载脚本块的尝试。我尝试在正文中传递JS脚本标记(如下面的代码所示),尝试,尝试

浏览器视角

从浏览器的角度来看,在部分刷新期间调用SSJS的事件中遇到运行时错误后,被调用的xhr返回500并将内容设置到body标记中(屏幕截图)

<script>
    alert('hi Marky!');
</script>

查看响应内容时,整个自定义错误XPage都在那里,包括
console.log(“hello world”)。这似乎不会触发或向浏览器的JS控制台输出任何内容。通过JS控制台可以看到dojo的一些垃圾,它们抱怨返回了响应代码为500的XHR(我的dojoConfig在xsp属性中通过xsp.client.script.dojo.djConfig设置为
isDebug:true

问题

在加载自定义错误XPage期间发生错误500后,是否有方法让客户端JS脚本标记加载并在浏览器中执行


这是我的错误页面的代码。要重现我的结果,请调用一个SSJS操作,该操作会导致运行时错误(例如Paul Withers的OpenLog Logger for XPages项目中包含的错误)和部分刷新事件

Error.xsp(设置为xsp属性中的错误页)


值得一提的是:我没有通过搜索谷歌或StackOverflow找到任何关于这个主题的明确信息


更新1: 这要么是咖啡因缺乏,要么就是看不见树林。在HTML代码中不使用CDATA块会有所帮助。我的懒惰开发人员尝试在xp:script块和HTML块之间复制和粘贴,并保留它。现在来谈谈在亚特兰大购买Marky啤酒的公众羞辱

更新2: Marky选择的饮料可能会有危险。虽然我似乎在复制CDATA标记时遇到了问题,但问题仍然存在。在我试图生成一个带有出错按钮的简化页面(松散地基于上面提到的XPages ErrorOnClick.xsp的OpenLog Logger中的XPage)时,我错误地取出了导致问题的部分原因,即部分刷新。当我进行完全刷新时,没有问题,但当我进行部分刷新时,它不会加载。我附上了一个示例页面,用两个按钮触发一个错误;一个是诱导一个完全的,另一个是部分的。所以,在完全刷新之后,我得到了一个“hello world…”的警报,带有部分,无骰子

MakeSomeError.xsp


更新3: 可以斯文的第二个答案让我非常接近,但出于某种原因,我无法推断出我想要发生的事情。我在我的结果下面加了一张GIF。唯一不同的是,我希望我的Error.xsp(自定义错误XPage)在遇到错误后继续加载(似乎我需要将beforeRenderResponse块更改为afterRenderResponse脚本)。我想附加脚本,而不是替换Error.xsp加载。基本上,我尝试在加载错误XPage后运行脚本(我尝试将一个helper JS文件加载到我的自定义错误XPage中,CSS加载正常,而不是JS库)。我很乐意:

  • 让它工作起来
  • 分享它是什么(如果我自己这么说的话,它有点酷)

  • 不要在
    脚本
    标记中使用
    CDATA

    var ex = facesContext.getExternalContext();
    var pMap = com.ibm.xsp.util.TypedUtil().getRequestParameterMap(ex);
    var refreshId = pMap.get("$$ajaxid");
    
    
    警惕(“你好,马克!”);
    

    对我来说很有用。

    之所以这样做是因为这是一种安全功能。如果浏览器是通过Ajax加载的,则不会执行
    块。 但有一个解决办法:

    首先,您必须添加一个div以替换呼叫XPage:

    var resp:com.ibm.xsp.webapp.XspHttpServletResponse = facesContext.getExternalContext().getResponse();
    resp.setStatus(200);
    
    现在必须将响应状态代码设置为200,否则将调用事件中的错误方法:

    resp.setHeader('X-XspRefreshId', 'errRefresh' );
    
    然后,您可以添加CSJS块,该块必须如下所示:

    facesContext.responseComplete();
    
    <xp:text
        escape="true"
        id="executeOnAjax"
        tagName="img">
        <xp:this.attrs>
            <xp:attr
                name="src"
                value="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==">
        </xp:attr>
            <xp:attr
                name="onload"
                value="alert('Hello World!');this.parentNode.removeChild(this);">
        </xp:attr>
        </xp:this.attrs>
        <xp:this.rendered>
            <![CDATA[#{javascript:
                var ex = facesContext.getExternalContext();
                var pMap = com.ibm.xsp.util.TypedUtil().getRequestParameterMap(ex);
                var refreshId = pMap.get("$$ajaxid");
                refreshId?true:false;}]]>
        </xp:this.rendered>
    </xp:text>
    
    最后但并非最不重要的一点是,我们必须跳过JSF生命周期:

    <script>
        if( !dojo._xhr )
            dojo._xhr = dojo.xhr;
    
            var myHandler = function(){
                var xhrObj = arguments[1].xhr;
                var response = xhrObj.response;
                var header = xhrObj.getResponseHeader('X-XspRefreshId');
                if( header == "@error" ){
                    eval( response );
                }else{
                    arguments[1]["error"]( arguments[0], arguments[1]);
                }
            }
    
        dojo.xhr = function(){        
            try{
                var args = arguments[1];   
                args["failOk"] = true;
                args["error"] = myHandler;
                arguments[1] = args;
            }catch(e){}
    
            dojo._xhr( arguments[0], arguments[1], arguments[2] );
        }
    </script>
    
    就这样

    以下是错误页面的beforeRenderResponse事件的完整代码:

    <xp:this.beforeRenderResponse>
        <![CDATA[#{javascript:    
        var ex = facesContext.getExternalContext();
        var pMap = com.ibm.xsp.util.TypedUtil().getRequestParameterMap(ex);
        var refreshId = pMap.get("$$ajaxid");
    
        if( refreshId ){
            var resp:com.ibm.xsp.webapp.XspHttpServletResponse = facesContext.getExternalContext().getResponse();
            var writer:java.io.PrintWriter = resp.getWriter();
            writer.write( "alert('Hello World!' );\n" );
            resp.setHeader('X-XspRefreshId', '@error' );
            facesContext.responseComplete();
        }
    }]]>
    </xp:this.beforeRenderResponse>
    
    
    
    Marky还有一个好主意:劫持响应

    这可能是这样的:

    facesContext.responseComplete();
    
    <xp:text
        escape="true"
        id="executeOnAjax"
        tagName="img">
        <xp:this.attrs>
            <xp:attr
                name="src"
                value="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==">
        </xp:attr>
            <xp:attr
                name="onload"
                value="alert('Hello World!');this.parentNode.removeChild(this);">
        </xp:attr>
        </xp:this.attrs>
        <xp:this.rendered>
            <![CDATA[#{javascript:
                var ex = facesContext.getExternalContext();
                var pMap = com.ibm.xsp.util.TypedUtil().getRequestParameterMap(ex);
                var refreshId = pMap.get("$$ajaxid");
                refreshId?true:false;}]]>
        </xp:this.rendered>
    </xp:text>
    
    
    如果(!dojo._xhr)
    dojo.xhr=dojo.xhr;
    var myHandler=function(){
    var xhrObj=参数[1].xhr;
    var响应=xhrObj.response;
    var header=xhrObj.getResponseHeader('X-XspRefreshId');
    如果(标题==“@错误”){
    评价(反应);
    }否则{
    参数[1][“错误”](参数[0],参数[1]);
    }
    }
    dojo.xhr=函数(){
    试一试{
    var args=参数[1];
    args[“failOk”]=真;
    args[“error”]=myHandler;
    参数[1]=args;
    }捕获(e){}
    dojo.xhr(参数[0],参数[1],参数[2]);
    }
    
    必须修改beforeRenderResponse事件,如下所示:

    facesContext.responseComplete();
    
    <xp:text
        escape="true"
        id="executeOnAjax"
        tagName="img">
        <xp:this.attrs>
            <xp:attr
                name="src"
                value="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==">
        </xp:attr>
            <xp:attr
                name="onload"
                value="alert('Hello World!');this.parentNode.removeChild(this);">
        </xp:attr>
        </xp:this.attrs>
        <xp:this.rendered>
            <![CDATA[#{javascript:
                var ex = facesContext.getExternalContext();
                var pMap = com.ibm.xsp.util.TypedUtil().getRequestParameterMap(ex);
                var refreshId = pMap.get("$$ajaxid");
                refreshId?true:false;}]]>
        </xp:this.rendered>
    </xp:text>
    
    
    
    <
    <xp:text
        escape="true"
        id="executeOnAjax"
        tagName="img">
        <xp:this.attrs>
            <xp:attr
                name="src"
                value="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==">
        </xp:attr>
            <xp:attr
                name="onload"
                value="alert('Hello World!');this.parentNode.removeChild(this);">
        </xp:attr>
        </xp:this.attrs>
        <xp:this.rendered>
            <![CDATA[#{javascript:
                var ex = facesContext.getExternalContext();
                var pMap = com.ibm.xsp.util.TypedUtil().getRequestParameterMap(ex);
                var refreshId = pMap.get("$$ajaxid");
                refreshId?true:false;}]]>
        </xp:this.rendered>
    </xp:text>