জাভাস্ক্রিপ্ট / ব্রাউজারে একটি জ্যাকোরি এজাক্স প্রতিক্রিয়া ক্যাশে করা হচ্ছে


100

আমি জাভাস্ক্রিপ্ট / ব্রাউজারে একটি অজ্যাক্স প্রতিক্রিয়া ক্যাচিং সক্ষম করতে চাই।

থেকে jquery.ajax ডক্স :

ডিফল্টরূপে, অনুরোধগুলি সর্বদা জারি করা হয় তবে ব্রাউজারটি এর ক্যাশে থেকে ফলাফলগুলি সরবরাহ করতে পারে। ক্যাশেড ফলাফলগুলির ব্যবহার নিষিদ্ধ করতে, ক্যাশেটিকে মিথ্যাতে সেট করুন। শেষ অনুরোধের পর থেকে যদি সম্পদটি সংশোধন না করা হয় তবে অনুরোধটিকে ব্যর্থতার প্রতিবেদন করার কারণ হিসাবে সেট করা হয়েছে যদি সেট করা হয়েছে সত্য হিসাবে।

তবে, এই ঠিকানাগুলির কোনওটিই জোর করে ক্যাশে দিচ্ছে না।

অনুপ্রেরণা: আমি $.ajax({...})আমার সূচনা ফাংশনগুলিতে কল রাখতে চাই, যার মধ্যে কয়েকটি অনুরূপ অনুরোধ করে। কখনও কখনও আমি এই সূচনা ফাংশনগুলির একটি কল করতে হবে, কখনও কখনও আমি বেশ কয়েকটি কল করি।

সুতরাং, আমি যদি সেই নির্দিষ্ট ইউআরএলটি ইতিমধ্যে লোড করা হয়ে থাকে তবে আমি সার্ভারের কাছে অনুরোধগুলি হ্রাস করতে চাই।

আমি আমার নিজস্ব সমাধানটি (কিছুটা অসুবিধা সহ!) রোল করতে পারি, তবে আমি জানতে চাই যে এটি করার কোনও মানক উপায় আছে কিনা।


আপনি ইতিমধ্যে কোন ইউআরএলগুলি লোড করেছেন এবং সেই তালিকার বিপরীতে ফলাফলগুলি সঞ্চয় করেছেন তা ট্র্যাক করতে আমি ভাবিনি। তারপরে, আপনি এজেএক্স কল করার আগে আপনার ইউআরএলগুলি পরীক্ষা করতে পারেন। ভয়েলা - আপনার নিজস্ব বেসিক ক্যাশে রয়েছে।

আপনি ক্যাশে-নিয়ন্ত্রণ যুক্ত করতে পারেন এবং সার্ভারে আপনার প্রতিক্রিয়াতে শিরোলেখের মেয়াদোত্তীর্ণ হতে পারে, সুতরাং আপনার সার্ভারটি আপনাকে সেই মানগুলিতে কনফিগার করা সময়সীমার পরে কেবল কল করা উচিত
এখানে

এটি খুব দীর্ঘ, তবে আপনি কেন আমাকে এজ্যাক্স অনুরোধে ক্যাশে প্রয়োজন বলে বুঝতে সাহায্য করতে পারেন (সম্ভবত সাধারণ লোকের দিক থেকে)
আশীশ

উত্তর:


146

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);
}

এবং মজাদার এখানে যত্নবান, with। ডিফার্ড

এখানে একটি কার্যক্ষম তবে ত্রুটিযুক্ত বাস্তবায়ন স্থগিতের সাথে কাজ করছে:

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
            });
        });
    });
});

ফিডল এখানে কিছু সমস্যা, আমাদের ক্যাশে আইডি json2 lib JSON অবজেক্ট উপস্থাপনার উপর নির্ভরশীল।

ক্যাশে দ্বারা উত্পাদিত কিছু লগ দেখতে কনসোল ভিউ (এফ 12) বা ফায়ারব্যাগ ব্যবহার করুন।


localCache.setফাংশনে আপনি কলব্যাক দেওয়ার কোনও কারণ আছে ? কেন কেবল doSomehing(jqXHR)ক্যাশে সেট করার পরে নয় ?
ক্যাম্মিল

আমি কেবল এটিকে পছন্দ করি তাই আমাকে এর মতো কিছু করতে হবে না doSomething(localCache.set(url,jqXHR));তবে এটি কেবল ব্যক্তিগত পছন্দ
TecHunter

4
প্রতিশ্রুতি হিসাবে aj .JAX ব্যবহার করে সমর্থন করার জন্য এটি উন্নত করার জন্য কোনও পরামর্শ? আগে থেকে মিথ্যা ফেরত পাঠানো অনুরোধটি বাতিল করে (যেমনটি হওয়া উচিত) তাই বিদ্যমান $ .জ্যাক্স (...)। সম্পন্ন (ফাংশন (প্রতিক্রিয়া) {...})। ব্যর্থ (...) এখন কাজ করা বন্ধ করুন কারণ ব্যর্থ হওয়ার পরিবর্তে আহ্বান করা হয়েছে সম্পন্ন হওয়ার চেয়ে ... এবং আমি তাদের
সবগুলিই আবার

4
@ টেকহান্টার এর জন্য অনেক ধন্যবাদ। আরও তিনটি হালকা উন্নতি করা যেতে পারে। প্রথমত, একই সময়ে যদি একই সংস্থানটিতে একাধিক অনুরোধ করা হয় তবে তারা সমস্ত ক্যাশে মিস করবে। এটি ঠিক করতে আপনি প্রথম অনুরোধের সাথে মুলতুবিতে নির্দিষ্ট "আইডি" এর জন্য ক্যাশে সেট করতে এবং প্রথমটি ফিরে না আসা পর্যন্ত পরবর্তী অনুরোধগুলির জন্য ফলাফল প্রেরণ স্থগিত করতে চাইতে পারেন। দ্বিতীয়ত, আপনি কোনও অনুরোধের ত্রুটির ফলাফলটি ক্যাশে করতে চাইতে পারেন যাতে একই উত্সের জন্য সমস্ত অনুরোধ একই ফলাফল পায়।
mjhm

4
@ টেকহান্টার - ভাল সমাধান, আমি এই সমাধানটি একটি গুরুত্বপূর্ণ পরিবর্তনের সাথে ব্যবহার করেছি। যদি ক্যাশেড অবজেক্টটি অন্য ফাংশনগুলিতে সংশোধন করা হচ্ছে তবে এটি সমস্যার কারণ হয়ে দাঁড়াবে, সুতরাং ক্যাশে অবজেক্টটি স্থাপন ও গ্রহণ করার সময়, আমি সেই বস্তুর অনুলিপি ফিরিয়ে দিচ্ছি যা নীচে দেখানো হয়েছে: localCache.data[url] = { _: new Date().getTime(), data: _.cloneDeep(cachedData, true) }; _.cloneDeep(localCache.data[url].data, true)
ভারত পাতিল

12

আমি আমার ফোনগ্যাপ অ্যাপ স্টোরেজটির জন্য ক্যাশে খুঁজছিলাম এবং আমি @ টেকহান্টারের উত্তর পেয়েছি যা দুর্দান্ত তবে ব্যবহার করে করা হয়েছে localCache

আমি খুঁজে পেয়েছি এবং জানতে পেরেছি যে অ্যাজাক্স কল দ্বারা ফিরিয়ে নেওয়া ডেটা ক্যাশে করার জন্য লোকালস্টোরেজ হল আরেকটি বিকল্প। সুতরাং, আমি একটি ডেমো ব্যবহার করে তৈরি করেছি localStorageযা অন্যদের যারা ক্যাশে ব্যবহারের localStorageপরিবর্তে ব্যবহার করতে চাইতে পারে তাদের সহায়তা করবে localCache

আজাক্স কল:

$.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!");
    }
});

লোকালস্টোরেজে ডেটা সঞ্চয় করতে:

$.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.removeItem("Info");

আশা করি এটি অন্যকে সহায়তা করবে!


হাই, ইন localStorage.removeItem("Info");, "info"এটি ইউআরএল সম্পর্কে ?
vsogrimen

@ ভোগগ্রিমেন লোকাল স্টোরেজে infoডেটা সংরক্ষণ করার বিষয়।
immayankmodi

4
পাওয়া চালিয়ে responseJSON is not defined। এটা সমাধান করার জন্য কোন রাস্তা আছে? (আমার ডেটাটাইপটি এইচটিএমএল)
নিকিতা 웃

@ ক্রিয়েটিভ মাইন্ড, পুনঃস্থাপন করুন JOSN সরান, এবং "var প্রতিক্রিয়াডাটা = JSON.stringify (ডেটা) ব্যবহার করুন;" পরিবর্তে, সাফল্যের সাথে একই করুন (ডেটা)
ইউনিকো

আমি একাধিক অনুরোধ জুড়ে ক্যাশে প্রয়োজন হিসাবে আমি স্থানীয় স্টোরারেজ পছন্দ করি।
কেইটেলডোগ

9

সমস্ত আধুনিক ব্রাউজার আপনাকে এপিআইএস সরবরাহ করে। আপনার ডেটা সংরক্ষণ করতে আপনি সেগুলি (লোকালস্টোরেশন বা সেশনসোজার) ব্যবহার করতে পারেন।

আপনাকে যা করতে হবে তা হ'ল প্রতিক্রিয়া পাওয়ার পরে এটি ব্রাউজার স্টোরেজে সঞ্চয় করে। তারপরে আপনি যখন একই কলটি খুঁজে পাবেন তখন প্রতিক্রিয়াটি ইতিমধ্যে সংরক্ষিত থাকলে অনুসন্ধান করুন। যদি হ্যাঁ, তবে সেখান থেকে প্রতিক্রিয়া ফিরিয়ে দিন; যদি একটি নতুন কল না।

স্মার্টজ্যাক্স প্লাগইন একই রকম কাজ করে; তবে আপনার প্রয়োজনীয়তা কেবলমাত্র কল প্রতিক্রিয়া সংরক্ষণ করছে, প্রতিক্রিয়াটি সংরক্ষণ করতে আপনি আপনার কোডটি আপনার jQuery এজাক্স সাফল্যের ফাংশনের ভিতরে লিখতে পারেন। এবং কল করার আগে কেবল প্রতিক্রিয়াটি ইতিমধ্যে সংরক্ষিত আছে কিনা তা পরীক্ষা করে দেখুন।


আমার প্রতিক্রিয়াগুলি ইনডেক্সডডিবিতে সংরক্ষিত আছে, ইনডেক্সডডিবি চেক করার কোনও উপায় আছে কি? এছাড়াও, আমি যদি সেশন স্টোরেজ ব্যবহার করি তবে প্রতিক্রিয়া উপস্থিত রয়েছে কি না jQuery ব্যবহার করছে কিনা তা পরীক্ষা করার কোনও উপায় আছে। আমি jQuery ব্যতীত অন্য কোনও লাইব্রেরি অন্তর্ভুক্ত করতে পারি না। ধন্যবাদ,
অভিষেক আগরওয়াল

7

যদি আমি আপনার প্রশ্নটি বুঝতে পারি তবে সমাধানটি এখানে দেওয়া হল:

    $.ajaxSetup({ cache: true});

এবং নির্দিষ্ট কলগুলির জন্য

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

যদি আপনি বিপরীতে চান (নির্দিষ্ট কলগুলির জন্য ক্যাশে) আপনি শুরুতে মিথ্যা সেট করতে পারেন এবং নির্দিষ্ট কলগুলির জন্য সত্য।


4
একেবারে উল্টো
টেকহান্টার

এটি আমার জন্য কাজ করে, আপনাকে ধন্যবাদ! আশ্চর্যজনক যে আমার পৃষ্ঠায় ডিফল্টরূপে ক্যাচিং সক্ষম করা হয়নি ..
তৈমুর নূরলিগায়ানভ

2

পুরানো প্রশ্ন, তবে আমার সমাধানটি কিছুটা আলাদা।

আমি একটি একক পৃষ্ঠার ওয়েব অ্যাপ্লিকেশন লিখছিলাম যা ব্যবহারকারীর দ্বারা নিয়মিত অজ্যাক্স কলগুলি চালিত করছিল এবং আরও জটিল করে তুলতে এটি লাইব্রেরিগুলির প্রয়োজন ছিল যা jquery ব্যতীত অন্যান্য পদ্ধতি ব্যবহার করেছিল (যেমন ডোজো, নেটিভ এক্সএইচআর ইত্যাদি)। এজ্যাক্স কল করার জন্য কোন লাইব্রেরি ব্যবহার করা হচ্ছে তা নির্বিশেষে আমি আমার নিজস্ব একটি লাইব্রেরির জন্য এজাক্স অনুরোধকে যথাসম্ভব দক্ষতার সাথে ক্যাশে করতে একটি প্লাগইন লিখেছিলাম ।

সমাধানটি জেএসকিউএল ব্যবহার করে (আমার দ্বারা লিখিত - জাভাস্ক্রিপ্টে লিখিত ক্লায়েন্ট-সাইড ধ্রুবক এসকিউএল বাস্তবায়ন যা ইন্ডেক্সডডিবি এবং অন্যান্য ডোম স্টোরেজ পদ্ধতি ব্যবহার করে), এবং এক্সএইচআরক্রিপ (আমার দ্বারা লিখিত) নামে একটি অন্য লাইব্রেরি দ্বারা বান্ডিল করা হয়েছে যা সম্পূর্ণ পুনরায় লেখার জন্য নেটিভ এক্সএইচআর অবজেক্ট।

আপনাকে যা করতে হবে তা বাস্তবায়নের জন্য আপনার পৃষ্ঠায় প্লাগইন অন্তর্ভুক্ত করা উচিত যা এখানে রয়েছে

দুটি বিকল্প রয়েছে:

jSQL.xhrCache.max_time = 60;

মিনিটে সর্বোচ্চ বয়স নির্ধারণ করুন। এর চেয়ে পুরানো যে কোনও ক্যাশেড প্রতিক্রিয়াগুলি পুনরায় অনুরোধ করা হয়। ডিফল্ট হয় 1 ঘন্টা।

jSQL.xhrCache.logging = true;

সত্য হিসাবে সেট করা হলে, মক এক্সএইচআর কলগুলি ডিবাগ করার জন্য কনসোলে প্রদর্শিত হবে।

আপনি যে কোনও প্রদত্ত পৃষ্ঠায় ক্যাশে সাফ করতে পারবেন

jSQL.tables = {}; jSQL.persist();

আমি আপনার প্লাগইনটি গিথুব এবং অফিসিয়াল ওয়েবসাইটে খুঁজে পাচ্ছি না lease দয়া করে আপনার উত্তরটি আপডেট করুন আমার আপনার প্লাগইন দরকার :) আমি গিথুবে আপনার অনুগামী। গুড জব;) @ occams-ক্ষুর
Alican Kablan

-1
        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();

লিঙ্ক বিবরণ এখানে লিখুন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.