0

Here's the deal - we have only one permutation so there is no need to perform any browser detection. We are optimizing for mobile devices and latency and network bandwidth are a problem. We have an alternate way to obtain the main fragment other than using an HTTP request and would like to utilize that but *.nocache.js only knows about creating a script tag that requests it via http.

I was trying to create a custom version of *.nocache.js (presently hacking) that will do enough of a setup to allow us to load the fragment code differently (as just directly loading the fragment does not seem to work, even when I unescape it - all code is inside a list of quoted strings passed to a function call). I managed to get that code running but it fails.

Any ideas?

4

1 回答 1

0

好吧,在上面 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;
      }

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

于 2018-01-31T18:32:59.360 回答