У меня есть функция на основе jquery, которая предварительно фильтрует все запросы ajax, чтобы перехватывать запросы 401 и обновлять авторизацию API. Раньше я использовал функцию, которая просто проверяет наличие ошибки 401, обновляет аутентификацию и повторно отправляет первоначальный запрос. Проблема заключалась в том, что одновременно запускалось множество обновлений, что обычно приводило к сбою. Я заменил его чем-то, что проверяет, происходит ли обновление, и если да, добавляет запросы в очередь. Теперь проблема, с которой я столкнулся, заключается в том, что исходные запросы не выполняют обещание и выдают ошибку, прежде чем их повторно запускают и добиваются успеха. Это проблема некоторых функций, которые не работают после последующего повторного запуска. Я хочу, чтобы перевыпуск ajax был прозрачным, чтобы мне не приходилось обрабатывать ошибки при каждом вызове ajax. В более простом коде этой проблемы не было. К сожалению, у меня недостаточно знаний, чтобы разобраться в логике обещаний.
Код префильтра выглядит следующим образом
var refreshQueue = [];
function addQueue(cb) {
refreshQueue.push(cb);
}
function onRefreshed(token) {
refreshQueue.forEach(cb => cb(token));
refreshQueue = [];
}
$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
// Skip refresh endpoint itself
if (options.url.includes('/refresh') || options.url.includes('refresh')) {
return;
}
// Add token to every request
var token = localStorage.getItem('access_token');
if (token) {
jqXHR.setRequestHeader('Authorization', 'Bearer ' + token);
}
// Hook into the fail handler
jqXHR.fail(function(jqXHR, textStatus, errorThrown) {
if (jqXHR.status === 401 && !originalOptions._retry) {
var retryOriginalRequest = new $.Deferred();
if (isRefreshing) {
// Wait for the ongoing refresh
addQueue(function(newToken) {
// Retry with new token
originalOptions.headers = originalOptions.headers || {};
console.log(originalOptions);
// originalOptions.headers['Authorization'] = 'Bearer ' + newToken;
originalOptions._retry = true;
$.ajax(originalOptions)
.then(retryOriginalRequest.resolve, retryOriginalRequest.reject);
});
} else {
// Start refresh
isRefreshing = true;
$.ajax({
url: 'api/refresh',
method: 'POST',
contentType: 'application/json',
data: JSON.stringify({
access_token: localStorage.getItem('access_token')
// or refresh_token: localStorage.getItem('refresh_token')
})
})
.done(function(res) {
var newToken = res.access_token || res.token;
localStorage.setItem('access_token', newToken);
// Update global headers for future requests
$.ajaxSetup({
headers: { 'Authorization': 'Bearer ' + newToken }
});
onRefreshed(newToken);
// Retry original
// originalOptions.headers['Authorization'] = 'Bearer ' + newToken;
originalOptions._retry = true;
$.ajax(originalOptions).then(retryOriginalRequest.resolve, retryOriginalRequest.reject);
})
.fail(function() {
console.log("Refresh fail");
onRefreshed(null); // notify all waiting requests failed
// Optional: logout
// localStorage.clear();
// location.href = '/login';
retryOriginalRequest.reject(jqXHR, textStatus, errorThrown);
})
.always(function() {
isRefreshing = false;
});
}
jqXHR.then(null, function() {
return retryOriginalRequest;
});
}
});
});```
Подробнее здесь: https://stackoverflow.com/questions/798 ... -prefilter
Ajax-запросы завершаются неудачно, а затем завершаются успешно при повторной попытке с предварительным фильтром ⇐ Jquery
Программирование на jquery
1765563229
Anonymous
У меня есть функция на основе jquery, которая предварительно фильтрует все запросы ajax, чтобы перехватывать запросы 401 и обновлять авторизацию API. Раньше я использовал функцию, которая просто проверяет наличие ошибки 401, обновляет аутентификацию и повторно отправляет первоначальный запрос. Проблема заключалась в том, что одновременно запускалось множество обновлений, что обычно приводило к сбою. Я заменил его чем-то, что проверяет, происходит ли обновление, и если да, добавляет запросы в очередь. Теперь проблема, с которой я столкнулся, заключается в том, что исходные запросы не выполняют обещание и выдают ошибку, прежде чем их повторно запускают и добиваются успеха. Это проблема некоторых функций, которые не работают после последующего повторного запуска. Я хочу, чтобы перевыпуск ajax был прозрачным, чтобы мне не приходилось обрабатывать ошибки при каждом вызове ajax. В более простом коде этой проблемы не было. К сожалению, у меня недостаточно знаний, чтобы разобраться в логике обещаний.
Код префильтра выглядит следующим образом
var refreshQueue = [];
function addQueue(cb) {
refreshQueue.push(cb);
}
function onRefreshed(token) {
refreshQueue.forEach(cb => cb(token));
refreshQueue = [];
}
$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
// Skip refresh endpoint itself
if (options.url.includes('/refresh') || options.url.includes('refresh')) {
return;
}
// Add token to every request
var token = localStorage.getItem('access_token');
if (token) {
jqXHR.setRequestHeader('Authorization', 'Bearer ' + token);
}
// Hook into the fail handler
jqXHR.fail(function(jqXHR, textStatus, errorThrown) {
if (jqXHR.status === 401 && !originalOptions._retry) {
var retryOriginalRequest = new $.Deferred();
if (isRefreshing) {
// Wait for the ongoing refresh
addQueue(function(newToken) {
// Retry with new token
originalOptions.headers = originalOptions.headers || {};
console.log(originalOptions);
// originalOptions.headers['Authorization'] = 'Bearer ' + newToken;
originalOptions._retry = true;
$.ajax(originalOptions)
.then(retryOriginalRequest.resolve, retryOriginalRequest.reject);
});
} else {
// Start refresh
isRefreshing = true;
$.ajax({
url: 'api/refresh',
method: 'POST',
contentType: 'application/json',
data: JSON.stringify({
access_token: localStorage.getItem('access_token')
// or refresh_token: localStorage.getItem('refresh_token')
})
})
.done(function(res) {
var newToken = res.access_token || res.token;
localStorage.setItem('access_token', newToken);
// Update global headers for future requests
$.ajaxSetup({
headers: { 'Authorization': 'Bearer ' + newToken }
});
onRefreshed(newToken);
// Retry original
// originalOptions.headers['Authorization'] = 'Bearer ' + newToken;
originalOptions._retry = true;
$.ajax(originalOptions).then(retryOriginalRequest.resolve, retryOriginalRequest.reject);
})
.fail(function() {
console.log("Refresh fail");
onRefreshed(null); // notify all waiting requests failed
// Optional: logout
// localStorage.clear();
// location.href = '/login';
retryOriginalRequest.reject(jqXHR, textStatus, errorThrown);
})
.always(function() {
isRefreshing = false;
});
}
jqXHR.then(null, function() {
return retryOriginalRequest;
});
}
});
});```
Подробнее здесь: [url]https://stackoverflow.com/questions/79845137/ajax-queries-failing-and-then-succeding-on-retry-with-prefilter[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия