jQuery-将Ajax响应存储到全局变量中


68

我仍然是jQuery和ajax场景的新手,但是我有一个$ .ajax请求,执行GET来检索一些XML文件(〜6KB或更少),但是在用户花那个页面的时间内,XML内容应该不会/不会更改(此设计我无法更改,在从其他地方读取XML文件时也无权更改它)。因此,我有一个全局变量将响应数据存储到该变量中,并且对该数据进行的所有后续查询都将在此变量上进行,因此不需要进行多个请求。

考虑到XML文件可以增加的事实,我不确定这是最佳做法,而且还来自Java背景,因此我对全局公共变量的想法通常是不可以的。

因此,我的问题是,是否可能有更好的方法来解决这个问题,以及如果文件扩展到某个可笑的文件大小,是否会导致任何内存问题?

我认为数据可以传递到xml对象内部的一些getter / setter类型的函数中,这可以解决我的全局公共变量问题,但仍然引发了一个问题,即我是否应该将响应存储在对象内部。

例如,我目前正在做的是:

// top of code
var xml;
// get the file
$.ajax({
  type: "GET",
  url: "test.xml",
  dataType: "xml",
  success : function(data) {
    xml = data;
  }
});
// at a later stage do something with the 'xml' object
var foo = $(xml).find('something').attr('somethingElse');

10
警告要探索的人。以下许多解决方案使用async:false。巨龙来了
卢克·谢弗

Answers:


35

除了存储它,别无他法。内存分页应减少那里的潜在问题。

我建议不要使用名为“ xml”的全局变量,而应执行以下操作:

var dataStore = (function(){
    var xml;

    $.ajax({
      type: "GET",
      url: "test.xml",
      dataType: "xml",
      success : function(data) {
                    xml = data;
                }
    });

    return {getXml : function()
    {
        if (xml) return xml;
        // else show some error that it isn't loaded yet;
    }};
})();

然后使用:

$(dataStore.getXml()).find('something').attr('somethingElse');

9
> [ALERT]此答案无效。阅读rfc1484下面的答案。
skozz 2014年

1
可能是因为缺少了$()。
卢克·谢弗

1
我同意@skozz,它不起作用。返回未定义。解决此问题的唯一方法似乎是使async false
约翰·R·佩里

70

这是一个功能很好的功能。我无法获得上述最佳答案。

jQuery.extend({
    getValues: function(url) {
        var result = null;
        $.ajax({
            url: url,
            type: 'get',
            dataType: 'xml',
            async: false,
            success: function(data) {
                result = data;
            }
        });
       return result;
    }
});

然后访问它,如下所示创建变量:

var results = $.getValues("url string");

3
实际上,仅添加'async:false'可以解决许多您将遇到的问题。
公鸡2012年

6
并可能导致很多问题,例如冻结浏览器几秒钟:)
Armen Markossyan

异步引起很多问题。有什么可以解决异步问题的呢?
Maciek Semik 2014年

这就是答案!!非常感谢
sixty4bit 2014年

4
这在chrome控制台中发出警告,例如Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check http://xhr.spec.whatwg.org/.
RN Kushwaha 2015年

35

这对我有用:

var jqxhr = $.ajax({
    type: 'POST',       
    url: "processMe.php",
    data: queryParams,
    dataType: 'html',
    context: document.body,
    global: false,
    async:false,
    success: function(data) {
        return data;
    }
}).responseText;

alert(jqxhr);
// or...
return jqxhr;

重要注意事项:global: falseasync:false最后responseText链接到$.ajax请求。


2
async:false会造成破坏!如果您有一个带有加载gif或其他内容的beforeSend,异步将使其变得非常难看
Maciek Semik 2014年

这对我来说就像一种魅力。我一直在努力将ajax响应存储到全局变量中,这很长时间了
King

17

您无需执行任何操作。我的项目遇到了同样的问题。您要做的是在on成功回调中进行函数调用以重置全局变量。只要将异步javascript设置为false,它就可以正常工作。这是我的代码。希望能帮助到你。

var exists;

//function to call inside ajax callback 
function set_exists(x){
    exists = x;
}

$.ajax({
    url: "check_entity_name.php",
    type: "POST",
    async: false, // set to false so order of operations is correct
    data: {entity_name : entity},
    success: function(data){
        if(data == true){
            set_exists(true);
        }
        else{
            set_exists(false);
        }
    }
});
if(exists == true){
    return true;
}
else{
    return false;
}

希望这对您有所帮助。


1
上帝喜欢为我解答:D
Aditzu

1
这个效果很好!只是一件事情,if(data == true)需要更改。它可能只是空的。
Maciek Semik 2014年

我试图从返回的响应ajax重新创建节点。每当我使用现有节点时,我的脚本都可以工作,但是当尝试重新创建由ajax响应构造的对象时,我的脚本却无法工作。这个解决方案对我有用。我现在不会探索,但是我怀疑异步设置会有所不同。
IberoMedia 2014年

这对我的项目效果非常好。我只使用了函数调用。不需要真正的虚假资料
user1794918

9

您可能会发现将响应值存储在DOM元素中更容易,因为它们可以全局访问:

<input type="hidden" id="your-hidden-control" value="replace-me" />

<script>
    $.getJSON( '/uri/', function( data ) {
        $('#your-hidden-control').val( data );
    } );
</script>

这具有不需要将async设置为false的优点。显然,这是否合适取决于您要实现的目标。


2
很简单!它对我有用,尽管不是使用设置输入值的方法,而是使用jQuery的.data()方法存储JSON。
安东尼

8

就此而言,您的问题可能与任何本地或全局范围都不相关,只是“成功”函数执行与您尝试从变量中取出数据之间的服务器延迟。

您可能会尝试在ajax“成功”函数触发之前打印变量的内容。


6
        function getJson(url) {
            return JSON.parse($.ajax({
                type: 'GET',
                url: url,
                dataType: 'json',
                global: false,
                async: false,
                success: function (data) {
                    return data;
                }
            }).responseText);
        }

        var myJsonObj = getJson('/api/current');

这有效!!!


3
     function get(a){
            bodyContent = $.ajax({
                  url: "/rpc.php",
                  global: false,
                  type: "POST",
                  data: a,
                  dataType: "html",
                  async:false
               } 
            ).responseText;
            return bodyContent;

  }

2

也碰到这个。但是,有很多答案,我只提供一个简单正确的答案。关键是使您的$ .ajax通话。

$.ajax({  
    async: false, ...

2
感谢您的降级,但是,嘿,我来这里是为了寻找一种解决方案,该解决方案的主体没有任何阻塞操作,对于其他可能在这个问题上绊倒的人,我的解决方案可能就是答案!
stvn 2012年

2
每个人都在讨论这个问题,所以我也应该这样做。从jQuery 1.8开始,async: false它已被弃用,并且始终有比同步请求更好的方法来处理代码。
安德鲁·拉尔森

2

我真的很难在事件的“ document.ready”阶段将jQuery ajax的结果放入变量中。

当用户在页面已加载后触发选择框的“ onchange”事件时,jQuery的ajax会加载到我的变量中,但是当页面首次加载时,数据不会提供变量。

我尝试了许多很多不同的方法,但是最后,查尔斯·吉尔伯特(Charles Guilbert)的方法对我来说最有效。

向查尔斯·吉尔伯特致敬!使用他的答案,即使页面首次加载,我也可以将数据获取到变量中。

这是工作脚本的示例:

    jQuery.extend
    (
        {
            getValues: function(url) 
            {
                var result = null;
                $.ajax(
                    {
                        url: url,
                        type: 'get',
                        dataType: 'html',
                        async: false,
                        cache: false,
                        success: function(data) 
                        {
                            result = data;
                        }
                    }
                );
               return result;
            }
        }
    );

    // Option List 1, when "Cats" is selected elsewhere
    optList1_Cats += $.getValues("/MyData.aspx?iListNum=1&sVal=cats");

    // Option List 1, when "Dogs" is selected elsewhere
    optList1_Dogs += $.getValues("/MyData.aspx?iListNum=1&sVal=dogs");

    // Option List 2, when "Cats" is selected elsewhere
    optList2_Cats += $.getValues("/MyData.aspx?iListNum=2&sVal=cats");

    // Option List 2, when "Dogs" is selected elsewhere
    optList2_Dogs += $.getValues("/MyData.aspx?iListNum=2&sVal=dogs");

1

我知道线程很旧,但我认为其他人可能会觉得有用。根据jquey.com

var bodyContent = $.ajax({
  url: "script.php",
  global: false,
  type: "POST",
  data: "name=value",
  dataType: "html",
  async:false,
  success: function(msg){
     alert(msg);
  }
}).responseText;

将有助于直接将结果获取到字符串。注意.responseText;部分。


0

IMO您可以将此数据存储在全局变量中。但是最好使用更多唯一的名称或使用名称空间:

MyCompany = {};

...
MyCompany.cachedData =数据;

并且最好将json用于这些目的,json格式的数据通常比xml格式的相同数据小得多。


当您使用大量全局变量时,这很不好,但是当您仔细使用它们时,这会很有帮助。JQuery使用全局变量(至少$和jQuery),ExtJS也使用全局变量。
zihotki 2009年

0

我建议应避免从服务器获取大型XML文件:变量“ xml”应像缓存一样使用,而不应作为数据存储本身使用。

在大多数情况下,可以检查缓存并查看是否需要向服务器发出请求以获取所需的数据。这将使您的应用更轻便,更快。

干杯,耶。


0

.get响应默认情况下被缓存。因此,您真的不需要执行任何操作即可获得所需的结果。


0

与先前的答案类似:

<script type="text/javascript">

    var wait = false;

    $(function(){
        console.log('Loaded...');
        loadPost(5);
    });

    $(window).scroll(function(){
      if($(window).scrollTop() >= $(document).height() - $(window).height()-100){
        // Get last item
        var last = $('.post_id:last-of-type').val();
        loadPost(1,last);
      }
    });

    function loadPost(qty,offset){
      if(wait !== true){

        wait = true;

        var data = {
          items:qty,
          oset:offset
        }

        $.ajax({
            url:"api.php",
            type:"POST",
            dataType:"json",
            data:data,
            success:function(data){
              //var d = JSON.parse(data);
              console.log(data);
              $.each(data.content, function(index, value){
                $('#content').append('<input class="post_id" type="hidden" value="'+value.id+'">')
                $('#content').append('<h2>'+value.id+'</h2>');
                $('#content').append(value.content+'<hr>');
                $('#content').append('<h3>'+value.date+'</h3>');
              });
              wait = false;
            }
        });
      }
    }
</script>

0

只是使用这个。简单有效:

var y;

function something(x){
return x;
}

$.get(bunch of codes, function (data){

y=something(data);
)}

//anywhere else
console.log(y);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.