it-source

jquery ajax 응답을 javascript/browser에서 캐시하는 중

criticalcode 2023. 3. 27. 21:18
반응형

jquery ajax 응답을 javascript/browser에서 캐시하는 중

javascript/browser에서 ajax 응답 캐시를 활성화하고 싶습니다.

jquery.ajax 문서에서:

기본적으로는 요청은 항상 발행되지만 브라우저는 캐시에서 결과를 제공할 수 있습니다.캐시된 결과를 사용할 수 없도록 하려면 캐시를 false로 설정합니다.마지막 요청 이후 자산이 수정되지 않은 경우 요청이 실패를 보고하도록 하려면 ifModified를 true로 설정합니다.

단, 이들 주소 중 어느 것도 캐시를 강제하지 않습니다.

동기:넣고 싶다$.ajax({...})초기화 함수의 콜, 그 중 일부는 같은 URL을 요구합니다.이러한 초기화 기능 중 하나를 호출해야 할 때도 있고 여러 번 호출해야 할 때도 있습니다.

따라서 해당 URL이 이미 로딩되어 있다면 서버에 대한 요청을 최소화하고 싶습니다.

(어렵게!) 독자적인 솔루션을 전개할 수 있습니다만, 표준적인 방법이 있는지 알고 싶습니다.

cache:true 및 합니다.

다음과 같은 방법으로 자신의 솔루션을 전개할 수 있습니다.

var localCache = {
    data: {},
    remove: function (url) {
        delete localCache.data[url];
    },
    exist: function (url) {
        return localCache.data.hasOwnProperty(url) && localCache.data[url] !== null;
    },
    get: function (url) {
        console.log('Getting in cache for url' + url);
        return localCache.data[url];
    },
    set: function (url, cachedData, callback) {
        localCache.remove(url);
        localCache.data[url] = cachedData;
        if ($.isFunction(callback)) callback(cachedData);
    }
};

$(function () {
    var url = '/echo/jsonp/';
    $('#ajaxButton').click(function (e) {
        $.ajax({
            url: url,
            data: {
                test: 'value'
            },
            cache: true,
            beforeSend: function () {
                if (localCache.exist(url)) {
                    doSomething(localCache.get(url));
                    return false;
                }
                return true;
            },
            complete: function (jqXHR, textStatus) {
                localCache.set(url, jqXHR, doSomething);
            }
        });
    });
});

function doSomething(data) {
    console.log(data);
}

여기서 바이올린을 켜다

편집: 이 투고가 인기를 끌면서 타임아웃 캐시를 관리하고 싶은 분들을 위해 더 좋은 답변이 있습니다.또한 $.ajax()의 모든 문제를 $.ajaxPrefilter()를 사용하고 있기 때문에 번거롭게 할 필요가 없습니다.이제 설정만 하면 됩니다.{cache: true}를 올바르게합니다.

var localCache = {
    /**
     * timeout for cache in millis
     * @type {number}
     */
    timeout: 30000,
    /** 
     * @type {{_: number, data: {}}}
     **/
    data: {},
    remove: function (url) {
        delete localCache.data[url];
    },
    exist: function (url) {
        return !!localCache.data[url] && ((new Date().getTime() - localCache.data[url]._) < localCache.timeout);
    },
    get: function (url) {
        console.log('Getting in cache for url' + url);
        return localCache.data[url].data;
    },
    set: function (url, cachedData, callback) {
        localCache.remove(url);
        localCache.data[url] = {
            _: new Date().getTime(),
            data: cachedData
        };
        if ($.isFunction(callback)) callback(cachedData);
    }
};

$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
    if (options.cache) {
        var complete = originalOptions.complete || $.noop,
            url = originalOptions.url;
        //remove jQuery cache as we have our own localCache
        options.cache = false;
        options.beforeSend = function () {
            if (localCache.exist(url)) {
                complete(localCache.get(url));
                return false;
            }
            return true;
        };
        options.complete = function (data, textStatus) {
            localCache.set(url, data, complete);
        };
    }
});

$(function () {
    var url = '/echo/jsonp/';
    $('#ajaxButton').click(function (e) {
        $.ajax({
            url: url,
            data: {
                test: 'value'
            },
            cache: true,
            complete: doSomething
        });
    });
});

function doSomething(data) {
    console.log(data);
}

그리고 여기 바이올린은 조심하세요. 달러로는 사용할 수 없습니다.지연

다음은 작동 중이지만 결함이 있는 구현입니다.

var localCache = {
    /**
     * timeout for cache in millis
     * @type {number}
     */
    timeout: 30000,
    /** 
     * @type {{_: number, data: {}}}
     **/
    data: {},
    remove: function (url) {
        delete localCache.data[url];
    },
    exist: function (url) {
        return !!localCache.data[url] && ((new Date().getTime() - localCache.data[url]._) < localCache.timeout);
    },
    get: function (url) {
        console.log('Getting in cache for url' + url);
        return localCache.data[url].data;
    },
    set: function (url, cachedData, callback) {
        localCache.remove(url);
        localCache.data[url] = {
            _: new Date().getTime(),
            data: cachedData
        };
        if ($.isFunction(callback)) callback(cachedData);
    }
};

$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
    if (options.cache) {
        //Here is our identifier for the cache. Maybe have a better, safer ID (it depends on the object string representation here) ?
        // on $.ajax call we could also set an ID in originalOptions
        var id = originalOptions.url+ JSON.stringify(originalOptions.data);
        options.cache = false;
        options.beforeSend = function () {
            if (!localCache.exist(id)) {
                jqXHR.promise().done(function (data, textStatus) {
                    localCache.set(id, data);
                });
            }
            return true;
        };

    }
});

$.ajaxTransport("+*", function (options, originalOptions, jqXHR, headers, completeCallback) {

    //same here, careful because options.url has already been through jQuery processing
    var id = originalOptions.url+ JSON.stringify(originalOptions.data);

    options.cache = false;

    if (localCache.exist(id)) {
        return {
            send: function (headers, completeCallback) {
                completeCallback(200, "OK", localCache.get(id));
            },
            abort: function () {
                /* abort code, nothing needed here I guess... */
            }
        };
    }
});

$(function () {
    var url = '/echo/jsonp/';
    $('#ajaxButton').click(function (e) {
        $.ajax({
            url: url,
            data: {
                test: 'value'
            },
            cache: true
        }).done(function (data, status, jq) {
            console.debug({
                data: data,
                status: status,
                jqXHR: jq
            });
        });
    });
});

여기서 문제 해결 캐시 ID는 json2 lib JSON 오브젝트 표현에 의존합니다.

캐시에 의해 생성된 일부 로그를 표시하려면 콘솔 뷰(F12) 또는 FireBug를 사용합니다.

앱 , @ @TecHunter를 하여 완성되었습니다.이 답변은 훌륭하지만 이미 사용되었습니다.localCache.

calllocalStorage에 또 . 제가 를 하나 요.localStorage이 될 수 것 같아요.localStoragelocalCache캐싱에 사용합니다.

Ajax 콜:

$.ajax({
    type: "POST",
    dataType: 'json',
    contentType: "application/json; charset=utf-8",
    url: url,
    data: '{"Id":"' + Id + '"}',
    cache: true, //It must "true" if you want to cache else "false"
    //async: false,
    success: function (data) {
        var resData = JSON.parse(data);
        var Info = resData.Info;
        if (Info) {
            customerName = Info.FirstName;
        }
    },
    error: function (xhr, textStatus, error) {
        alert("Error Happened!");
    }
});

데이터를 localStorage에 저장하려면:

$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
if (options.cache) {
    var success = originalOptions.success || $.noop,
        url = originalOptions.url;

    options.cache = false; //remove jQuery cache as we have our own localStorage
    options.beforeSend = function () {
        if (localStorage.getItem(url)) {
            success(localStorage.getItem(url));
            return false;
        }
        return true;
    };
    options.success = function (data, textStatus) {
        var responseData = JSON.stringify(data.responseJSON);
        localStorage.setItem(url, responseData);
        if ($.isFunction(success)) success(responseJSON); //call back to original ajax call
    };
}
});

localStorage를 제거하려면 원하는 위치에서 다음 문을 사용하십시오.

localStorage.removeItem("Info");

다른 사람들에게 도움이 되길!

최신 브라우저는 모두 스토리지 아피스를 제공합니다.이러한 파일(local스토리지 또는 session스토리지)을 사용하여 데이터를 저장할 수 있습니다.

브라우저 저장소에 응답을 받은 후 저장하기만 하면 됩니다.다음에 같은 콜을 검출했을 경우는, 응답이 이미 보존되어 있는지를 검색합니다.[네(Yes)]의 경우는, 거기서 응답을 반환합니다.신규 콜을 발신하지 않는 경우는, 그 응답을 반환합니다.

Smartjax 플러그인도 비슷한 작업을 수행합니다.단, 필요한 것은 호출 응답 저장뿐이므로 jQuery ajax 성공 함수에 코드를 입력하여 응답을 저장할 수 있습니다.그리고 전화를 걸기 전에 응답이 이미 저장되었는지 확인합니다.

당신의 질문을 이해했다면, 해결책은 다음과 같습니다.

    $.ajaxSetup({ cache: true});

및 특정 콜의 경우

 $.ajax({
        url: ...,
        type: "GET",
        cache: false,           
        ...
    });

반대(특정 콜의 캐시)를 원할 경우 처음에 false를 설정하고 특정 콜에 true를 설정할 수 있습니다.

오래된 질문이지만, 제 해결책은 좀 달라요.

한 페이지 웹 앱에 사용자가 트리거한 Ajax 콜을 계속 발신하고 있었는데, 더 어렵게 하기 위해서는 jquery 이외의 메서드(dojo, native xhr 등)를 사용하는 라이브러리가 필요했습니다.어떤 라이브러리가 Ajax 호출에 사용되고 있는지에 관계없이 모든 주요 브라우저에서 동작하는 방법으로 가능한 한 효율적으로 Ajax 요청을 캐시하기 위해 내 라이브러리하나를 위한 플러그인을 작성했습니다.

이 솔루션은 jSQL(제가 작성한 클라이언트 측 영속 SQL 구현 - indexeddb 및 기타 dom 스토리지 방법을 사용하는 javascript)을 사용하며, 네이티브 XHR 개체를 완전히 다시 쓰는 XHRCreep(제가 작성한)이라는 다른 라이브러리와 번들되어 있습니다.

구현하려면 여기에 있는 페이지에 플러그인을 포함하기만 하면 됩니다.

두 가지 옵션이 있습니다.

jSQL.xhrCache.max_time = 60;

최대 경과시간(분)을 설정합니다.캐시된 응답 중 이보다 오래된 응답은 다시 검색됩니다.기본값은 1시간입니다.

jSQL.xhrCache.logging = true;

true로 설정하면 디버깅을 위해 콘솔에 모의 XHR 콜이 표시됩니다.

임의의 페이지의 캐시를 클리어 할 수 있습니다.

jSQL.tables = {}; jSQL.persist();
        function getDatas() {
            let cacheKey = 'memories';

            if (cacheKey in localStorage) {
                let datas = JSON.parse(localStorage.getItem(cacheKey));

                // if expired
                if (datas['expires'] < Date.now()) {
                    localStorage.removeItem(cacheKey);

                    getDatas()
                } else {
                    setDatas(datas);
                }
            } else {
                $.ajax({
                    "dataType": "json",
                    "success": function(datas, textStatus, jqXHR) {
                        let today = new Date();

                        datas['expires'] = today.setDate(today.getDate() + 7) // expires in next 7 days

                        setDatas(datas);

                        localStorage.setItem(cacheKey, JSON.stringify(datas));
                    },
                    "url": "http://localhost/phunsanit/snippets/PHP/json.json_encode.php",
                });
            }
        }

        function setDatas(datas) {
            // display json as text
            $('#datasA').text(JSON.stringify(datas));

            // your code here
           ....

        }

        // call
        getDatas();

링크 설명을 여기에 입력하십시오.

언급URL : https://stackoverflow.com/questions/17104265/caching-a-jquery-ajax-response-in-javascript-browser

반응형