Обновление: Переписанный для слияния предложений от John Millikin и da5id. Это решение записано в PHP, но должно быть легко адаптировано к другим языкам.
Обновление 2: Слияние комментариев от Nick Johnson, что оригинал .htaccess
regex может вызвать проблемы с файлами как json-1.3.js
. Решение состоит в том, чтобы только переписать, если существует точно 10 цифр в конце. (Поскольку 10 цифр покрывают все метки времени с 09.09.2001 до 20.11.2286.)
Во-первых, мы используем следующее, переписывают правило в .htaccess:
RewriteEngine on
RewriteRule ^(.*)\.[\d]{10}\.(css|js)$ $1.$2 [L]
Теперь, мы пишем следующую функцию PHP:
/**
* Given a file, i.e. /css/base.css, replaces it with a string containing the
* file's mtime, i.e. /css/base.1221534296.css.
*
* @param $file The file to be loaded. Must be an absolute path (i.e.
* starting with slash).
*/
function auto_version($file)
{
if(strpos($file, '/') !== 0 || !file_exists($_SERVER['DOCUMENT_ROOT'] . $file))
return $file;
$mtime = filemtime($_SERVER['DOCUMENT_ROOT'] . $file);
return preg_replace('{\\.([^./]+)$}', ".$mtime.\$1", $file);
}
Теперь, везде, где Вы включаете свой CSS, изменяете его от этого:
<link rel="stylesheet" href="/css/base.css" type="text/css" />
К этому:
<link rel="stylesheet" href="<?php echo auto_version('/css/base.css'); ?>" type="text/css" />
Таким образом, Вы никогда не должны изменять тег link снова, и пользователь будет всегда видеть последний CSS. Браузер сможет кэшировать файл CSS, но когда Вы внесете любые изменения в свой CSS, браузер будет рассматривать это как новый URL, таким образом, он не будет использовать кэшируемую копию.
Это может также работать с изображениями, favicons, и JavaScript. В основном что-либо, что динамично не сгенерировано.
Вам нужно будет отвязать событие и либо выполнить повторную привязку к отдельному событию, которое не предотвращает значение по умолчанию, либо просто вызвать событие по умолчанию самостоятельно позже в методе после отмены привязки. Магического события нет .cancelled = false;
По запросу
$('form').submit( function(ev){
ev.preventDefault();
//later you decide you want to submit
$(this).unbind('submit').submit()
});
Либо вы делаете то, что предлагает redsquare, с помощью этого кода:
function preventDefault(e) {
e.preventDefault();
}
$("form").bind("submit", preventDefault);
// later, now switching back
$("form#foo").unbind("submit", preventDefault);
, либо вы назначаете атрибут формы всякий раз, когда разрешена отправка. Примерно так:
function preventDefault(e) {
if (event.currentTarget.allowDefault) {
return;
}
e.preventDefault();
}
$("form").bind("submit", preventDefault);
// later, now allowing submissions on the form
$("form#foo").get(0).allowDefault = true;
$('form').submit( function(e){
e.preventDefault();
//later you decide you want to submit
$(this).trigger('submit'); or $(this).trigger('anyEvent');