AJAX POST 请求被缓存

Posted

技术标签:

【中文标题】AJAX POST 请求被缓存【英文标题】:AJAX POST requests being cached 【发布时间】:2014-11-25 23:14:54 【问题描述】:

在我的 Web 应用程序中,我正在向 URL /navigate.php 发送一个 POST 请求。它的工作方式应有尽有。

问题是,这个 Web 应用程序也应该可以离线工作。我将在由于连接问题导致请求无法完成时显示通知,并且用户可以在问题解决后再次同步。

当我出于调试目的断开 Internet 连接时,我发现请求仍然每次都返回 200 状态代码。

浏览器不应该缓存 POST 请求,我错了吗?

在 Stack Overflow 上搜索后,我尝试了这里写的解决方案。

我在 url 中附加了一个缓存破坏 (new Date().getTime()),但没有任何变化。请求仍然返回 200。

我尝试从服务器 (PHP/Ubuntu) 发送以下标头:

header("Expires: Sat, 01 Jan 2005 00:00:00 GMT");
header("Last-Modified: ".gmdate( "D, d M Y H:i:s")."GMT");
header("Cache-Control: no-cache, no-store");
header("Pragma: no-cache");

我没有将 jQuery 用于 AJAX(因为我只需要将它用于 AJAX,仅此而已),否则我会使用它的 cache 选项,并将其设置为 false。但我猜它做同样的事情,在 url 上附加一个缓存失败。

我正在使用以下代码发送请求:

define([],function()

var a=[

    function()return new XMLHttpRequest(),
    function()return new ActiveXObject("Msxml2.XMLHTTP"),
    function()return new ActiveXObject("Msxml3.XMLHTTP"),
    function()return new ActiveXObject("Microsoft.XMLHTTP")

];

    var o=function()

        var r=false;

        for(var i=0;i<a.length;i++) 

            try

                r=a[i]();

             catch(e) 

                continue;

            

            break;

        

        return r;

    ;

    var verifyParam = function(param) 
        if(typeof param === "undefined" || param === null) 
            return false;
         else 
            return true;
        
    ;

    var checkParam = function(param,defaultValue) 
        if(!verifyParam(param)) 
            return defaultValue;
         else 
            return param;
        
    ;

    var generateCacheBust = function() 
        return (new Date().getTime());
    ;

    var request = function(url,method,dataInPost,initCallback,callback,error) 

        var req = o();

        if(!req) return false;

        initCallback = checkParam(initCallback,function());

        callback = checkParam(callback,function());

        error = checkParam(error,function());

        initCallback(req);

        req.open(method,url,true);

        if(dataInPost) 

            req.setRequestHeader('Content-type','application/x-www-form-urlencoded');

        

        req.onreadystatechange = function() 

            if(req.readyState!=4) 

                return;

            

            try 

                if(req.status!=200 && req.status!=304) 

                    error(req.status);

                    return;

                 else 

                    callback(req);

                

             catch (e) 

                error(req.status);

                return;

            

        

        if(req.readyState == 4) return;

        try 

            req.send(dataInPost);

         catch (e) 

            error(req.status);

            return;

        

    ;

    var dataToString = function(data) 

        var string = '';

        for(var key in data) 

            string += (encodeURIComponent(key)+'='+encodeURIComponent(data[key])+'&');

        

        return string.substring(0,string.length-1);

    

    var formattedResponse = function(req,type) 

        var responseData = req.responseText;

        if(type=="json") 

            return JSON.parse(responseData);

         else 

            return responseData;

        

    

    var get = function(params) 

        if(!verifyParam(params.url))  return false; 

        params.data = checkParam(params.data,);

        params.responseType = checkParam(params.responseType,'text');

        params.init = checkParam(params.init,function());

        params.success = checkParam(params.success,function());

        params.error = checkParam(params.error,function());

        params.cache = checkParam(params.cache,true);

        if(!params.cache) params.data.cacheBust = generateCacheBust();

        request(params.url+'?'+dataToString(params.data),"GET",false,params.init,function(req)

            params.success(formattedResponse(req,params.responseType));

        ,params.error);

    ;

    var post = function(params) 

        if(!verifyParam(params.url))  return false; 

        params.data = checkParam(params.data,);

        params.responseType = checkParam(params.responseType,'text');

        params.init = checkParam(params.init,function());

        params.success = checkParam(params.success,function());

        params.error = checkParam(params.error,function());

        params.cache = checkParam(params.cache,true);

        if(!params.cache) params.url += "?" + "cacheBust=" + generateCacheBust();

        request(params.url,"POST",dataToString(params.data),params.init,function(req)

            params.success(formattedResponse(req,params.responseType));

        ,params.error);

    ;

    return 

        get:get,

        post:post

    ;

);

在网络日志 (Firefox) 上,这里是 firebug 显示的标头

请求标头:

POST /explorer/ajax/navigate.php?cacheBust=1412147821832 HTTP/1.1
Host: genortal.com
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://genortal.com/dashboard.php
Content-Length: 12
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache

响应标头:

HTTP/1.1 200 OK
Date: Wed, 01 Oct 2014 07:17:01 GMT
Server: Apache/2.4.7 (Ubuntu)
X-Powered-By: PHP/5.5.9-1ubuntu4.3
Expires: Sat, 01 Jan 2005 00:00:00 GMT
Cache-Control: no-cache, no-store
Pragma: no-cache
Last-Modified: Wed, 01 Oct 2014 07:17:02GMT
Content-Length: 744
Keep-Alive: timeout=5, max=79
Connection: Keep-Alive
Content-Type: application/json

这是我断开互联网连接后得到的标题:

请求标头:

POST /explorer/ajax/navigate.php?cacheBust=1412148166275 HTTP/1.1
Host: genortal.com
Connection: keep-alive
Content-Length: 12
Cache-Control: no-cache
Pragma: no-cache
Origin: http://genortal.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36
Content-type: application/x-www-form-urlencoded
Accept: */*
Referer: http://genortal.com/dashboard.php
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8

响应标头:

HTTP/1.1 200 OK
Date: Wed, 01 Oct 2014 07:22:46 GMT
Server: Apache/2.4.7 (Ubuntu)
X-Powered-By: PHP/5.5.9-1ubuntu4.3
Expires: Sat, 01 Jan 2005 00:00:00 GMT
Cache-Control: no-cache, no-store
Pragma: no-cache
Last-Modified: Wed, 01 Oct 2014 07:22:47GMT
Content-Length: 117
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: application/json

服务器端代码:

<?php
/**
 * Generation Portal
 * Date: 24/9/14
 * Time: 8:59 PM
 */

require_once '../../start_session.php';
require_once '../../libload.php';

use GenerationPortal\Genortal\Accounts\Session;
use GenerationPortal\Genortal\RequestIn;
use GenerationPortal\Genortal\ErrorDictionary\AjaxErrors;
use GenerationPortal\Genortal\AjaxHandler;
use GenerationPortal\Genortal\Explorer\Navigator;
use GenerationPortal\Genortal\Storage\DatabaseLayer;
use GenerationPortal\Genortal\FileSystem\FileSystem;

header("Expires: Sat, 01 Jan 2005 00:00:00 GMT");
header("Last-Modified: ".gmdate( "D, d M Y H:i:s")."GMT");
header("Cache-Control: no-cache, no-store");
header("Pragma: no-cache");

$requestIn = new RequestIn();

$ajaxHandler = new AjaxHandler();

if(!Session::loggedIn()) 

    $ajaxHandler->error('not_signed_in',AjaxErrors::desc('not_signed_in'));



if(!$requestIn->paramSet('path')) 

    $ajaxHandler->error('missing_parameters',AjaxErrors::desc('missing_parameters'));



$navigator = new Navigator();

try 

    $databaseLayer = new DatabaseLayer();

    $fileSystem = new FileSystem(Session::uid(),$requestIn->param('path'),$databaseLayer);

 catch (\Exception $e) 

    $ajaxHandler->error('server_error',AjaxErrors::desc('server_error'));



$ajaxHandler->respond($navigator->parseDirectoryListing($fileSystem));

谁能提供关于这里发生了什么的快速帮助?这是 HTTP 缓存的工作吗?

【问题讨论】:

你的请求在哪里,我们怎么猜 @meda 道歉,我不明白你想说什么...... @abhishek 他要求你展示代码,而不仅仅是用你自己的话来解释它。查看浏览器的网络活动 - 这些请求的发送位置和方式。 @abhishek,请分享您的代码? @RamSharma 是的,请稍等,我正在编辑问题 【参考方案1】:

您应该尝试为此目的使用缓存清除。我的意思是传递一个额外的参数,它是你的 URL 的变量,类似于这样

www.mydomain.com/navigate.php; //url without cache bust parameter
myRand=parseInt(Math.random()*99999999); 
www.mydomain.com/navigate.php?rand=54321 //url with cache bust parameter

所以在上述缓存中,您的服务器会将其理解为新请求。

【讨论】:

仔细阅读问题..I appended a cache bust (new Date().getTime()) to the url, but there was no change @ram 正如我在问题中提到的那样,我已经添加了当前时间戳【参考方案2】:

问题不在于代码、浏览器或 HTTP 缓存。问题出在我的操作系统上。即使我强制断开连接,连接也没有断开。我解决了我重新启动桌面的问题。

抱歉浪费了大家一点时间!谢谢。

【讨论】:

以上是关于AJAX POST 请求被缓存的主要内容,如果未能解决你的问题,请参考以下文章

Ajax相关(原生ajax,jQuery中ajax,axios)

AJAX get() 和 post() 方法

jQuery – AJAX get() 和 post() 方法

解析ajax请求post和get的区别

jQuery之异步Ajax请求使用

Nginx POST 请求缓存的使用