Jquery getScript缓存

默认情况下,$ .getScript()禁用缓存,您可以使用$ .ajaxSetup并将缓存设置为true。 当测试脚本是否实际上是用Firebug缓存时,脚本大部分时间都会返回200(这意味着脚本是一个新的副本),一个可能会在20或30次内返回304(意味着它使用了缓存)版)。 为什么绝大部分时间都会收到新版本?

$.ajaxSetup({ cache: true }); $.getScript( scriptFile ); 

尚未编辑getScript检索的文件,并且请求是页面更改。

首先让我们澄清一下jQuery禁用缓存的含义。

当jQuery 禁用缓存时 ,意味着强制文件由浏览器以某种技巧再次加载它 ,例如通过在URL的末尾添加一个额外的随机数作为参数。

当jQuery 启用缓存时不强制执行任何操作,并让您在此文件的标头上设置缓存 。 这意味着如果您没有设置文件参数的标头以将其保留在浏览器缓存中,浏览器将尝试通过某些方法再次加载它。

因此,通过jQuery启用缓存,您还必须在静态文件上设置正确的缓存头以保留在浏览器缓存上,否则浏览器可能会尝试再次加载它们。

对于浏览器在标题上看到创建日期的文件,然后连接到服务器再次询问标题,比较它,如果没有更改,则不再加载它,但是对服务器进行一次调用。

对于已设置最大年龄的文件,并且在该日期之前不询问服务器,如果浏览器找到它,则直接从缓存中加载它。

总结一下
cache:true让浏览器根据您发送的标头决定该文件的缓存。
cache:false强制文件再次加载。

一些相关的缓存问题:
缓存JavaScript文件
IIS7缓存控制

内部代码
getScript()调用jQuery.get()是一个简写的Ajax函数

 $.ajax({ url: url, data: data, success: success, dataType: dataType }); 

因此,通过调用getScript()您可以进行ajax调用,并且jQuery没有保留文件的任何缓存,如果这是您首先想到的。

用于加载手柄的自定义function
如果您没有赢得全局缓存:true,并且您只需要使用cache:true加载一些文件,则可以将自定义函数设置为:

 function getScriptCcd(url, callback) { jQuery.ajax({ type: "GET", url: url, success: callback, dataType: "script", cache: true }); }; 

这不受全局缓存参数的影响,并且加载脚本文件而不添加任何非缓存参数。

发布此问题的日期出现错误,Firefox和Chrome都会声明脚本未从Cache加载。 截至本答复之日,此问题仍然存在。 最简单的测试方法是使用console.log并发送版本号。

要缓存动态加载的脚本,只需使用以下代码即可完成。

 function onDemandScript ( url, callback ) { callback = (typeof callback != 'undefined') ? callback : {}; $.ajax({ type: "GET", url: url, success: callback, dataType: "script", cache: true }); } 

对于开发,您应该注释掉cache:true。

我知道这是一个老post,现有的答案是真正的答案,但触及Iscariot的担忧,它真的是在缓存(至少有点儿)。 这只是firefox的一个怪癖。 也许这对于被这个怪癖搞糊涂的人来说会有用。

我用一个非常大的javascript文件测试了这个概念,该文件基于成千上万个latlons的数组定义了Idaho DOT区域边界的谷地图多边形(未压缩文件大小为2,806,257,但我通过压缩过程运行它)。 使用以下javascript

 // Grab polys if not already loaded if (typeof(defaults.data.polys) === 'undefined') { /*$.getScript('/Scripts/ScriptMaster.php?file=Districts', function () {});*/ $.ajax({ type: "GET", url: '/Scripts/ScriptMaster.php?file=Districts', success: function() { defaults.data.polys = getPolys(); data.polys = defaults.data.polys; }, dataType: "script", cache: true }); } 

你可以看到相关的php(你不想要实际的Districts.js文件,这篇文章需要占用太多空间,所以这里是ScriptMaster.php)

  

重要的是要注意调用php的头函数之前脚本甚至执行你要打印的字符串,因为不像chrome和可能(可能,我只是懒得检查)其他浏览器firefox似乎对服务器执行ping操作在使用缓存之前检查标头。 也许通过更多的研究,你可以确定它是否与ajax(可能不是)一样与元素相关。

所以我做了五次测试运行,用firebug中所述的ajax显示了这个脚本的加载时间。 结果如下

 #results loading the script after clearing cache (yes those are seconds, not ms) 200 OK 4.89s 200 OK 4.9s 200 OK 5.11s 200 OK 5.78s 200 OK 5.14s #results loading the page with control+r 200 OK 101ms 200 OK 214ms 200 OK 24ms 200 OK 196ms 200 OK 99ms 200 OK 109ms #results loading the page again by navigating (not refreshing) 200 OK 18ms 200 OK 222ms 200 OK 117ms 200 OK 204ms 200 OK 19ms 200 OK 20ms 

正如您所看到的,我的本地主机服务器到Web客户端连接并不是最一致的,我的笔记本电脑规格有点破旧(单核处理器和所有,它也有几年了)但是要点是负载显着下降加载缓存后的时间。

[如果没有压缩脚本的任何人好奇(不喜欢标签,空格或新行被浪费,它只需要仍然可读)需要7到8秒之间加载,但我不会那样做五次]

所以永远不要害怕,它真的是缓存。 对于只加载ms的较小脚本,你可能没有注意到firefox的区别,老实说; 只是因为它检查服务器的标头。 我知道这是因为从脚本末尾移动那些头函数到开始时加载时间的变化。 如果你在php经过字符串后有这些function,则需要更长时间才能加载。

希望这可以帮助!

默认情况下,$ .getScript()将缓存设置设置为false。 这会将带时间戳的查询参数附加到请求URL,以确保浏览器在每次请求时都下载脚本。

jQuery doc site有一个很好的扩展,可以不为请求添加时间戳并绕过缓存:

 jQuery.cachedScript = function( url, options ) { // Allow user to set any option except for dataType, cache, and url options = $.extend( options || {}, { dataType: "script", cache: true, url: url }); // Use $.ajax() since it is more flexible than $.getScript // Return the jqXHR object so we can chain callbacks return jQuery.ajax( options ); }; // Usage $.cachedScript( "ajax/test.js" ).done(function( script, textStatus ) { console.log( textStatus ); }); 

资源

实际上有一个更好的选择,您可以为某些请求打开缓存,例如:

 $.ajaxPrefilter(function( options ) { if ( options.type==='GET' && options.dataType ==='script' ) { options.cache=true; } }); 

您可能正在寻找的是一个getScriptOnce函数,基本上,如果它知道文件已经成功加载,则在调用此类函数时不再加载此类文件。

我写了这样的function。 您可以使用Firebug或Chrome开发工具中的“ 网络”选项卡进行测试。 这只会加载同一个文件一次。 您只需getScriptOnce函数和全局数组ScriptArray复制到您的文件中

 var getScriptOnce = (function(url, callback) { var scriptArray = []; //array of urls return function (url, callback) { //the array doesn't have such url if (scriptArray.indexOf(url) === -1){ if (typeof callback === 'function') { return $.getScript(url, function(script, textStatus, jqXHR) { scriptArray.push(url); callback(script, textStatus, jqXHR); }); } else { return $.getScript(url, function(){ scriptArray.push(url); }); } } //the file is already there, it does nothing //to support as of jQuery 1.5 methods .done().fail() else{ return { done: function () { return { fail: function () {} }; } }; } } }()); /*#####################################################################*/ /*#####################################################################*/ //TEST - tries to load the same jQuery file twice var jQueryURL = "https://code.jquery.com/jquery-3.2.1.js"; console.log("Tries to load #1"); getScriptOnce(jQueryURL, function(){ console.log("Loaded successfully #1") }); //waits 2 seconds and tries to load again window.setTimeout(function(){ console.log("Tries to load #2"); getScriptOnce(jQueryURL, function(){ console.log("Loaded successfully #2"); }); }, 2000);