用 grunt 生成一个 blob,它将在 var 中提供给 JS

Generate a blob with grunt which will be available to JS in var

我需要在页面上嵌入 Flash .swf,但无法使用将 src 或数据属性设置为 swf 的正常方法 url - 不要问 :s。因此,我正在对 swf 执行 ajax 请求,转换为 blob,然后生成一个 blob url,我将其设置为 swf src。然后我意识到,当我使用 Grunt 进行构建时,可能有一种方法可以将 swf 文件作为 var 中的 blob 写入代码,并完全避免 ajax 请求。这是带有 ajax 请求的代码:

function createFlashMovie(blobUrl){
     var obj = document.createElement("object");
     obj.setAttribute("width", "800");
     obj.setAttribute("height", "600");
     obj.setAttribute("type", "application/x-shockwave-flash");
     obj.setAttribute("data", blobUrl);
     document.body.appendChild(obj);
}

function onAjaxLoad(oResponse){
    blobUrl = window.URL.createObjectURL(oResponse);
    createFlashMovie(blobUrl);
};

//do the xhr request for a.swf
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
    if (this.readyState == 4 && this.status == 200){
        onAjaxLoad(this.response);
    }
}
xhr.open('GET', '//theserver.com/a.swf');
xhr.responseType = 'blob';
xhr.send(); 

...但我确信必须有这样的东西,它被 grunt 取代,以便在运行时让 blob 可用,然后直接创建 blob url 而无需xhr 请求:

var theBlob = new Blob(["GRUNT_WRITES_THIS_IN_FROM_FILE"], {type: "application/x-shockwave-flash"});

好吧,grunt 的核心只是一个 Node 程序,因此您可以在 Gruntfile 或任务定义中使用任何节点命令。 Node 的 http.request 似乎非常适合您的需求。

所以:

  1. 在您的 Gruntfile 中添加自定义任务 (http://gruntjs.com/creating-tasks#custom-tasks)
  2. 使用 http.request 下载您的 swf (https://docs.nodejitsu.com/articles/HTTP/clients/how-to-create-a-HTTP-request)
  3. 更新您的代码以使用本地 swf

我找到了解决办法。将您的 swf 文件转换为 base64 编码的字符串。目前我正在单独执行此操作,然后将其粘贴到源 JS 中,但它可以在构建时使用 grunt 自动执行。然后在页面脚本中创建一个 var 将其存储为 dataURI:

var swfAsDataUri = "data:application/x-shockwave-flash;base64,BIG_LONG_CHUNK_OF_DATA_THAT_IS_YOUR_ENCODED_SWF_FILE__GRUNT_CAN_WRITE_THIS_IN_AT_BUILD_TIME";

从数据 url 创建一个 blob,然后从该 blob 创建一个对象 url:

//function taken from 
dataURLToBlob = function(dataURL) {
    var BASE64_MARKER = ';base64,';
    var parts = dataURL.split(BASE64_MARKER);
    var contentType = parts[0].split(':')[1];
    var raw = window.atob(parts[1]);
    var rawLength = raw.length;
    var uInt8Array = new Uint8Array(rawLength);
    for (var i = 0; i < rawLength; ++i) {
        uInt8Array[i] = raw.charCodeAt(i);
    }
    return new Blob([uInt8Array], {type: contentType});
};

var blobUrl = window.URL.createObjectURL( dataURLToBlob(swfAsDataUri) );

然后您可以使用对象 url 作为嵌入 flash 影片对象标签的 src 数据:

function createFlashMovie(blobUrl){
    var obj = document.createElement("object");
    obj.setAttribute("width", "800");
    obj.setAttribute("height", "600");
    obj.setAttribute("type", "application/x-shockwave-flash");
    obj.setAttribute("data", blobUrl); //use the object url here
    document.body.appendChild(obj);
}

...好了,swf 文件没有额外的 http 请求。