【问题标题】:What is the best way to customize or entirely skip GWT's *.nocache.js自定义或完全跳过 GWT 的 *.nocache.js 的最佳方法是什么
【发布时间】:2018-01-29 17:39:56
【问题描述】:

这是交易 - 我们只有一个排列,因此无需执行任何浏览器检测。我们正在针对移动设备进行优化,延迟和网络带宽是一个问题。除了使用 HTTP 请求之外,我们还有另一种获取主要片段的方法,并且希望利用它,但 *.nocache.js 只知道创建一个通过 http 请求它的脚本标记。

我试图创建一个自定义版本的 *.nocache.js(目前是 hacking),它会做足够的设置以允许我们以不同的方式加载片段代码(因为直接加载片段似乎不起作用,即使我取消它 - 所有代码都在传递给函数调用的带引号的字符串列表中)。我设法让该代码运行,但它失败了。

有什么想法吗?

【问题讨论】:

  • 你试过<add-linker name="sso"/>吗?
  • 好建议。我会。我完全忘记了这一点(可能是因为我们真的从来没有搞砸过)。
  • OK ...我尝试了这个并且更进一步...但是当我尝试直接注入脚本时(createElement,而不是 )整个文档变成空的 (Chrome) 或有 (Firefox)。查找此内容发现这可能与“computeScriptBase”有关,并且脚本预计其模块名称会出现在 URL 库中……但事实并非如此(这是从上一层的页面加载的)。现在与它作斗争......
  • 好吧,我在这方面做了 hack,但它是一个 hack。 computeScriptBase() 是罪魁祸首——它几乎是脚本调用的第一件事(除了设置提供程序、值等),而 computeScriptBase() 做的第一件事就是 document.write()。因此,在添加脚本并在之后返回它之前,我用一个虚拟实现替换了 document.write。为了获得正确的基数,我还必须为脚本临时插入一个 元素,然后将其更正回原始值。哎呀!

标签: gwt gwt-2.8


【解决方案1】:

好吧,在上面 Thomas Broyer 的评论之后,我能够更进一步并找到(目前)明确的答案:“这不可能干净地。 " (不编写自定义链接器)...但是我仍在进一步追求一种不太干净的方法。

具体来说,有三个官方 GWT 链接器,其中两个生成的代码本身想要通过 http 请求主代码片段。第三个,“sso”产生一个文件,只适用于一个排列(这在我的情况下是可以接受的)。但是,生成的代码会执行 document.write(),它会在动态调用时删除主文档。

它这样做是为了在它期望来自的标签之后创建一个标记标签,以便它可以从中提取自己的 URL 和脚本基础 URI。在我的情况下,主机页面位于 GWT 模块文件夹的父文件夹中,通常包含以下内容:

<script ... src="moduleName/moduleName.nocache.js"></script>

... 并且 moduleName.nocache.js 想要找出所有其他与模块相关的请求(例如其他代码片段等)的“host-base/moduleName”基本 URI。

在任何情况下,如果它无法找到它使用 document.write() 写入的标记标记,它将尝试查找标记并使用它。麻烦的是,该标签既不正常存在,也不正确——在我们的例子中,它会引用所需内容的父级。但是,这个标签也可以在我们实际注入 moduleName.nocache.js 之前动态插入...,然后在注入后纠正回来。

类似:

      // Obtain the main fragment script code using alternate means:
      var scriptCode = ...;

      // Create the script tag for the main code fragment
      var codeElement = document.createElement("script");
      codeElement.type = "text/javascript";
      
      // Prepare the environment to run it, to hack around
      // its document.write and base URI needs.
      
      // First remember the normal/original document.write method:
      var originalWriteMethod = document.write;
      
      // ... and replace it with a dummy one (we'll put this back later):
      document.write = function() {}
      
      // ... and also remember the document base
      var originalBase = document.baseURI;
      
      // Figure out the script base based on the originalBase:
      var scriptBase = originalBase + "moduleName/";
      
      // Failing document.write case, the main code fragment will look for
      // the last <base> tag to get the script base. Add that element and
      // set it to reference the scriptBase (we'll have to undo this later):
      var baseElement = document.createElement("base");
      baseElement.href = scriptBase;
      document.head.appendChild(baseElement);
      
      // Different browsers work differently...  try to cover two cases:
      try {
        codeElement.appendChild.document.createTextNode(scriptCode);
        document.head.appendChild(codeElement);
      } catch (e) {
        codeElement.text = scriptCode;
        document.head.appendChild(codeElement);
      } finally {
        // Whatever case occurred above, we must return the document.write()
        // to normal implementation and undo our temporary document base 
        // change:
        document.write = originalWriteMethod;
        baseElement.href = originalBase;
      }

这会让代码“加载”、初始化和运行。我还有一些测试要做,但这是迄今为止我最接近的一次。

【讨论】:

  • 可以更新 SSO 以避免使用 document.write - 考虑为 GWT 提供补丁?请记住,任何 SO 答案都在许多用户可能无法使用的许可下:stackoverflow.com/help/licensing
猜你喜欢
  • 2015-12-11
  • 2022-07-03
  • 2021-06-09
  • 2011-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-28
  • 2012-04-28
相关资源
最近更新 更多