Проблема с кнопкой "Назад" в Safari

Я немного занимаюсь программированием и работаю в Интернете в местном общественном колледже. Работа, которая включает в себя поддержку очень большого и душераздирающего веб-сайта, состоящего из мешанины VBScript, javascript, сгенерированного Dreamweaver мусора и набора надстроек, которые различные мошенники убеждали их покупать на протяжении многих лет.

Несколько дней назад мне позвонили: «Веб-сайт блокируется для людей, использующих Safari!» Хорошо, на первом этапе загрузите Safari (v3.1.2), на втором этапе перейдите на сайт. Кажется, все работает нормально.

Короче говоря, я, наконец, изолировал проблему, и она связана с кнопкой возврата Safari. На веб-сайте используется необычное меню javascript, которое работает во всех браузерах, которые я пробовал, включая Safari, впервые. Но в Safari, если вы перейдете по ссылке со страницы, а затем нажмете кнопку «Назад», меню больше не будет работать.

Я сделал урезанную веб-страницу, чтобы проиллюстрировать принцип.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head><title>Safari Back Button Test</title>
<meta http-equiv = "Content-Type" content = "text/html; charset=iso-8859-1">
</head>
<body onload = "alert('Hello');">
<a href = "http://www.codinghorror.com">Coding Horror</a>
</body>
</html>

Загрузите страницу, и вы увидите окно предупреждения. Затем перейдите по ссылке со страницы и нажмите кнопку «Назад». В IE и Firefox вы снова видите окно с предупреждением, а в Safari - нет.

После энергичного поиска в Google я обнаружил других людей с похожими проблемами, но без удовлетворительных ответов. Итак, мой вопрос: как я могу заставить мои страницы работать в Safari так же, как в других браузерах, после того, как пользователь нажмет кнопку «Назад»?

Если это глупый вопрос, будьте осторожны, javascript для меня в новинку.

Привет, Авто, ты еще не понял это? Я пробовал все приведенные ниже решения на iPad и iPod, и я не могу заставить Safari запускать JavaScript, когда клиент нажимает кнопку «Назад». (Я могу получить его, когда попробую с Safari на настольном компьютере, но не могу заставить его работать с мобильной версией Safari. Вы вообще с этим работали?)

Sal 16.08.2012 03:22

Проверьте ответ на вопрос Кнопка возврата мобильного Safari

Mika Tuupola 29.09.2012 15:25

Событие onload () не запускается в Safari при нажатии кнопки возврата

Mladen Janjetovic 15.05.2014 12:45

Сэл. В конце концов, я понял это. Я вызвал свою функцию с помощью jquery «document.ready» вместо «onload».

Autodidact 30.07.2015 18:02
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
45
4
36 137
11

Ответы 11

Я понятия не имею, в чем проблема, но знаю, кто может вам помочь. Safari построен на Webkit, и, если не считать Apple (которая не так настроена на сообщество), Команда Webkit может знать, в чем проблема.

Это совсем не глупый вопрос.

Я заметил нечто очень похожее. Я думаю, это потому, что Firefox и IE, возвращаясь назад, снова получают страницу с сервера, а Safari - нет. Вы пробовали добавить заголовок истечения срока действия / отсутствия кеша? Я собирался изучить это, когда обнаружил поведение, но еще не успел.

Iframe решает проблему:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head><title>Safari Back Button Test</title>
<meta http-equiv = "Content-Type" content = "text/html; charset=iso-8859-1">
</head>
<body onload = "alert('Hello');">
<a href = "http://www.codinghorror.com">Coding Horror</a>
<iframe style = "height:0px;width:0px;visibility:hidden" src = "about:blank">
this prevents back forward cache
</iframe>
</body>
</html>

узнать больше Детали

Ссылка в этом ответе теперь не работает; вы можете найти детали заархивированы здесь.

Simon Lieschke 21.01.2011 05:40

Решение Стефана iframe работает, но если оно недостаточно элегантно, я считаю, что следующий JavaScript также решает его:

window.onunload = function(){};

То есть, если в вашем меню используется JavaScript, вы можете также предпочесть решить эту проблему с помощью JavaScript.

Идея определения обработчика событий выгрузки пришла из статьи о Firefox 1.5: https://developer.mozilla.org/en/Using_Firefox_1.5_caching.

У меня были проблемы с кнопкой «Назад» в Safari, хотя я БЫЛ ИСПОЛЬЗОВАЛ событие jQuery $ (document) .ready. Я добавил приведенный выше код, и проблема была решена.

Ben Foster 01.02.2011 19:27

Похоже, что эти вопросы и ответы все еще актуальны. Рассматривая причуды браузера, можно думать только об IE, но у «других» (Webkit, Firefox) они тоже есть, хотя более незначительные и более неуловимы ...

kasimir 01.03.2012 12:44

@Mika Tuupola: Safari доступен не только на iOS. Я не понимаю, какую роль играет операционная система в поведении Safari, у вас тоже должна быть более новая версия Safari. У меня нет устройств iOS, поэтому пожимать плечами.

Lee Kowalkowski 29.09.2012 23:07

@LeeKowalkowski, ОС действительно влияет на это - Safari для iOS не работает, а версия OS X делает работает!

Jesse 07.04.2013 16:05

@Jesse: Тогда они явно разные звери! Я думаю, что удалю этот ответ. Я действительно не могу помочь людям, которые не видят проблемы, используя событие onload в первую очередь (подсказка: это не лучшее событие и, вероятно, не то, что вы думаете, то есть: оно запускается слишком поздно)

Lee Kowalkowski 07.04.2013 16:26

@LeeKowalkowski Не нужно удалять! У вас достаточно голосов, чтобы заслужить достойный ответ! Просто укажите, что предоставленное исправление, как известно, работает только в Firefox, но iOS Safari требует чего-то другого.

Jesse 07.04.2013 16:35

Большой! Это решило мою проблему, когда Safari не запускал событие onload () при нажатии кнопки возврата

Mladen Janjetovic 15.05.2014 12:43

В 2021 году выглядит, что уже не работает. Любое предложение?

Aral Roca 04.02.2021 20:57

Я знаю, что этой теме уже год, но я только что исправил идентичную проблему, связанную только с Safari, с помощью исправления обратной кнопки Safari в ProjectSeven. Работает как шарм.

http://www.projectseven.com/extensions/info/safaribbfix/index.htm

Это забавно, потому что ProjectSeven был меню JavaScript, о котором я говорил. В конце концов бросил его на самодельный jquery. Переход от onload в теге body к документу jquery. Уже решил проблему для меня.

Autodidact 02.06.2010 01:00

Просто вставьте это в тег тела <body onunload = "">

это заставит safari, chrome, FF перезагружаться каждый раз, когда вы нажимаете кнопку "Назад"

Вот хорошее решение для Mobile Safari:

/*! Reloads page on every visit */
function Reload() {
    try {
        var headElement = document.getElementsByTagName("head")[0];
        if (headElement && headElement.innerHTML)
            headElement.innerHTML += " ";
        } catch (e) {}
    }

    /*! Reloads on every visit in mobile safari */
    if ((/iphone|ipod|ipad.*os 5/gi).test(navigator.appVersion)) {
        window.onpageshow = function(evt) {
            if (evt.persisted) {
                document.body.style.display = "none";
                location.reload();
            }
        };
    }

(источник)

Я модифицировал его под свои нужды, но пока все в порядке. (раздражающий белый экран при обновлении, если вы его не изменяете).

Одинокая ссылка - считается плохим ответом, поскольку сама по себе бессмысленна, и не гарантируется, что целевой ресурс будет активен в будущем. Пожалуйста, постарайтесь включить хотя бы краткое изложение информации, на которую вы ссылаетесь.

j0k 06.09.2012 11:17

Была такая же проблема на iPad.

Не то чтобы красиво, но работает :). Как это устроено.

Я понял, что в iPad Safari страница не перезагружалась при нажатии кнопки «Назад». Я помещаю счетчик каждую секунду на страницу и сохраняю текущую временную метку.

Когда страница загружается, счетчик и время синхронизируются. На кнопке «Назад» счетчик продолжает с того места, где он остановился, и между меткой времени и счетчиком есть промежуток. Если разрыв больше 500 мс, перезагрузите страницу принудительно.

В файле action.js

var showLoadingBoxSetIntervalVar;
var showLoadingBoxCount = 0;
var showLoadingBoxLoadedTimestamp = 0

function showLoadingBox(text) {

    var showLoadingBoxSetIntervalVar=self.setInterval(function(){showLoadingBoxIpadRelaod()},1000);
    showLoadingBoxCount = 0
    showLoadingBoxLoadedTimestamp = new Date().getTime();

    //Here load the spinner

}

function showLoadingBoxIpadRelaod()
{
    //Calculate difference between now and page loaded time minus threshold 500ms
    var diffTime = ( (new Date().getTime()) - showLoadingBoxLoadedTimestamp - 500)/1000;

    showLoadingBoxCount = showLoadingBoxCount + 1;
    var isiPad = navigator.userAgent.match(/iPad/i) != null;

    if (diffTime > showLoadingBoxCount && isiPad){
        location.reload();
    }
}

Пожалуйста, не следуйте советам игнорировать кеш. Страницы кэшируются не просто так - для удобства пользователей. Используемые вами методы ухудшат взаимодействие с пользователем, поэтому не делайте этого, если вы не ненавидите своих пользователей.

Правильным решением для Safari (Desktop и iOS) является использование события pageshow вместо события onload (см. https://developer.mozilla.org/en-US/docs/Using_Firefox_1.5_caching, что это такое).

Событие pageshow сработает одновременно с ожидаемым срабатыванием события onload, но оно также будет работать, когда страницы обслуживаются через кеш. В любом случае это похоже на то, что вы хотите.

Действительно? Если js каким-то образом изменил страницу, например, чтобы указать счетчик на кнопке, который указывает процесс, а затем загружена новая страница, то при обратной навигации вы увидите этот счетчик на кнопке. И это не так, как должно быть

Sergey P. aka azure 22.07.2016 12:29

@ SergeyP.akaazure, поэтому вы используете событие pagehide, чтобы остановить счетчик.

bluesmoon 22.07.2016 16:23

$(window).bind("pageshow", function(event) {
  if (event.originalEvent.persisted) {
    window.location.reload() 
  }
});

Недавно ответил здесь от мшах.

Попробуй это
если (performance.navigation.type == 2) {
alert ("Привет");
}

Хотя это может быть ценным советом для решения проблемы, хороший ответ также демонстрирует решение. Пожалуйста, РЕДАКТИРОВАТЬ, чтобы предоставить пример кода, чтобы показать, что вы имеете в виду. В качестве альтернативы, вы можете написать это как комментарий.

ρяσѕρєя K 09.01.2020 16:21

Другие вопросы по теме