Мне нужно использовать navigator.sendBeacon() при выгрузке окна, чтобы мой сервер знал, что клиент закрыл свое окно. Я искал везде, и это просто не работает для меня.
Для справки: решение в эта почта тоже не сработало.
У меня есть компонент приложения, который охватывает весь мой проект. Я пытаюсь установить событие выгрузки для его componentDidMount() метода жизненного цикла, и оно просто не срабатывает.
componentDidMount() {
window.addEventListener("beforeunload", this.unload);
}
componentWillUnmount() {
window.addEventListener("beforeunload", this.unload);
}
unload(e) {
e.preventDefault();
e.returnValue = 'test';
navigator.sendBeacon(`http://localhost:8080/window-closed/${this.props.username}`);
return 'test';
}
Я ожидаю, что сервер получит вызов AJAX, а окно предложит пользователю «тестировать» перед закрытием окна. Что на самом деле происходит, так это то, что окно просто закрывается, как обычно.
ПРИМЕЧАНИЕ: утверждения return 'test' и e.returnValue = '' предназначены исключительно для тестирования. Меня интересует только запрос AJAX.
Любая помощь приветствуется.
Попробуйте заменить unload(e) { на unload = (e) => {
К сожалению, это не сработало :/ @GabrielePetrioli



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я не уверен, почему beforeunload не работает, но в качестве обходного пути вы можете рассмотреть возможность использования события hashchange.
componentDidMount() {
window.addEventListener("hashchange", this.doSomething, false);
}
componentWillUnmount() {
window.removeEventListener("hashchange", this.doSomething, false);
}
Вы пытались объявить функцию загрузки как функцию толстой стрелки? Также объявите его перед componentDidMount. (для лучшей читаемости) перед передачей в качестве ссылки.
Также вы пытались подключить прослушиватель в конструкторе? И сделайте surw для привязки вашей функции в конструкторе. Для справки
Также уничтожьте прослушиватель в componentWillUnmount вместо его добавления. (бесполезно) использовать ссылку на слушателя, чтобы уничтожить. Который вы создадите в конструкторе.
Удачи
Я не уверен, как вы имеете в виду, что я должен объявить это в конструкторе. Не могли бы вы показать мне какой-нибудь пример?
Constructor (){ this.unload = this.unload.bind(this) И объявить выгрузку с помощью функции стрелки
Также не рекомендуется добавлять прослушиватели событий в реакцию, но пока вы можете использовать описанный выше подход, чтобы все исправить (y)
Вы должны привязать это к методу выгрузки или преобразовать его в функцию стрелки.
Запойный способ
constructor() {
super();
this.state = {
//stuff
};
this.unload.bind(this);
}
componentDidMount() {
window.addEventListener("beforeunload", this.unload);
}
componentWillUnmount() {
window.removeEventListener("beforeunload", this.unload);
}
unload(e) {
navigator.sendBeacon(`http://localhost:8080/window-closed/${this.props.username}`);
}Стрелка работает так:
constructor() {
super();
this.state = {
//stuff
};
}
componentDidMount() {
window.addEventListener("beforeunload", this.unload);
}
componentWillUnmount() {
window.removeEventListener("beforeunload", this.unload);
}
unload = (e) => {
navigator.sendBeacon(`http://localhost:8080/window-closed/${this.props.username}`);
}Не забудьте удалить прослушиватель событий на componentWillUnmount (сейчас вы добавляете его снова).
Спасибо, воспользовался функциями стрелок, и он внезапно начал работать как шарм.
что, если у нас есть подсказка. Например, «Внесенные вами изменения могут быть не сохранены». даже пользователь нажимает кнопку отмены, вызывая «перед выгрузкой» оконную функцию!
Вы можете использовать navigator.sendBeacon.
const UnloadBeacon = ({
url,
payload = () => {},
children
}) => {
const eventHandler = () => navigator.sendBeacon(url, payload())
useEffect(() => {
window.addEventListener('unload', eventHandler, true)
return () => {
window.removeEventListener('unload', eventHandler, true)
}
}, [])
return children
}
полный пример здесь: https://gist.github.com/tmarshall/b5433a2c2acd5dbfc592bbc4dd4c519c
Если вы используете функциональный компонент, вы можете попробовать следующее:
useEffect(() => {
window.addEventListener("beforeunload", handleUnload);
return () => {
window.removeEventListener("beforeunload", handleUnload);
};
}, []);
const handleUnload = (e) => {
const message = "o/";
(e || window.event).returnValue = message; //Gecko + IE
return message;
};
Эй, у меня сейчас похожая проблема, не могли бы вы проверить это? stackoverflow.com/questions/67498997/…
Не могли бы вы предоставить коды и ящик?