Jef*_*mon 7 html javascript php ajax jquery
我们在网站上的许多地方使用了 ajax。一个实例有时会表现得不规则,就像 ajax 调用失败一样。它仅在一个特定位置 - 所有其他位置都按预期工作。
发生故障时,用户会收到操作失败的错误消息。
我们无法重现失败。它总是只适合我们。大多数用户没有遇到这个问题。少数确实这样做的人有时会报告说,他们后来又尝试了一次,并且成功了。
我们可以通过重命名ajax脚本来模拟失败。然后,当尝试操作时,ajax 调用失败,我们收到相同的错误消息。然而,我们没有任何理由相信该错误是由于无法访问 ajax 脚本引起的,尽管有可能。如果是这样的话,那么我们的其他 ajax 脚本也会出现同样的问题。
我们想出了一个解决方法。如果用户在尝试操作之前进入隐身模式,则可以避免该问题。
隐身模式解决方法表明它可能与 cookie 有关。因此,我们尝试以某种方式干扰 cookie,以尝试重现该问题。什么都没有成功。
为了帮助排除故障,我们在错误消息中添加了额外的诊断信息,但到目前为止,除了类似于“错误”的信息之外,还没有任何结果。下面是一些代码,显示了我们如何尝试获取更多信息:
error: function (jqXHR, textStatus, errorThrown)
{
// alert('read-unread error');
ajaxError('Read-Unread', textStatus, errorThrown); // TODO comment out to suppress the error reporting
},
Run Code Online (Sandbox Code Playgroud)
为了完整起见,我在下面包含了完整的 JavaScript 函数。
建立一个简单的测试环境来演示问题效果并不好,因为它会过于简化真实环境,从而破坏了其测试价值。我们认为唯一合理的测试是模拟用户正在做的用例。不幸的是,这很复杂,因为它涉及在我们的系统上创建个人资料,尝试使用该系统与其他成员进行通信,从其他成员那里获得一些响应通信,然后尝试回复此类通信。这会重新创建用例以及发生故障的位置。不幸的是,我们再次怀疑它仍然永远不会触发我们的失败——玩具系统也会“正常工作”。
如果每个用户每次都发生这种情况,那是一回事,但事实并非如此。某些时候只有部分用户使用,并且仅用于我们网站上众多 ajax 使用中的一种。一旦它开始发生,至少在一段时间内该用户就可以重复。
我的问题:
我们如何创建一个精简版本的环境,以便让 stackoverflow 社区值得一看,而不是模拟我们网站的使用?
“隐身模式”解决方法是否提供了任何见解来了解出了什么问题?
除了诊断在大多数情况下都能正常工作的代码之外,了解其他 Ajax 故障模式也会很有帮助。作为一个虚构的例子,例如“某些系统太慢并且ajax超时”。
[JavaScript 函数。注意:由于某种原因,我无法将函数的前几行放入代码标记中。]
function toggleReadUnread(usertypeid, opp_user_label_short, principalid, repid, contactuid, value) {
var new_response = (value) ? 'read' : 'unread';
var prefix = '#' + contactuid;
$('#ur-read-unread-text').html(new_response);
$('#read-unread-dialog').dialog
({
show: "fade",
title: "Change to " + new_response + "?",
modal: true,
resizeable: false,
width: getDialogWidth(400, .9),
maxWidth: 400,
fluid: true,
buttons:
{
Ok: function ()
{
$(this).dialog('close');
$.ajax(
{
// async: false
type: 'POST',
url: '/ajax/set-var.php',
// url: '/ajax/tr-toggle-status.php',
data:
{
'which_function': 'read-unread',
'principalid': principalid,
'repid': repid,
'usertypeid': usertypeid,
'value': value
},
error: function (jqXHR, textStatus, errorThrown)
{
// alert(jqXHR.responseText);
ajaxError('Read-Unread', textStatus, errorThrown);
},
success: function (data, textStatus, jqXHR)
{
if (data)
{
var connector = '\', \'';
if (value)
{
$(prefix + '-unread').remove();
$('<i id="' + contactuid + '-read" class="fa fa-envelope-open tooltip" onclick="toggleReadUnread(\'' + usertypeid + connector + opp_user_label_short + connector + principalid + connector + repid + connector + contactuid + '\'' + ', false);"><span id="' + contactuid + '-read-unread-tt" class="tooltiptext">You have no unread messages from this ' + opp_user_label_short + '</span>').insertAfter(prefix + '-read-unread-placeholder');
}
else
{
$(prefix + '-read').remove();
$('<i id="' + contactuid + '-unread" class="fa fa-envelope tooltip" onclick="toggleReadUnread(\'' + usertypeid + connector + opp_user_label_short + connector + principalid + connector + repid + connector + contactuid + '\'' + ', true);"><span id="' + contactuid + '-read-unread-tt" class="tooltiptext">You have a new message from this ' + opp_user_label_short + '</span>').insertAfter(prefix + '-read-unread-placeholder');
$('.tc-' + contactuid).hide();
}
jConfirm('Success', 'Messages marked "' + new_response + '"');
}
}
})
},
Cancel: function () {
$(this).dialog('close');
}
}
})
}
Run Code Online (Sandbox Code Playgroud)
编辑1:
我们仍然与用户遇到这个问题。我们仍然无法在内部重现它。
隐身可以防止问题的发生。虽然这应该是一个很好的线索,但到目前为止还没有帮助我们。它似乎指向会话和缓存问题。我们已经排除了过时的缓存问题。
它是间歇性的,仅影响少数用户。稍后甚至该用户也将不再遇到问题。再次似乎与缓存相关。
我们添加了诊断信息,有时在 ajax 错误抛出中显示“禁止”。检查这意味着它与跨域操作有关。没有进行跨域活动;所有请求都发送到我们自己的服务器。
我们向一些用户询问了他们的扩展。在一种情况下,他们没有安装扩展;在另一种情况下,他们只有 Chrome 的 Grammarly 扩展。我们使用该扩展进行了测试,但仍然无法重现该问题。
发生错误时,会显示一个对话框。单击该对话框上的“确定”后,其余操作应该继续进行,因为该对话框没有阻止任何内容。然而,用户报告说,如果不处于隐身模式,他们无法完成该操作。
编辑2:
我开始研究 https-access.log。虽然大多数对 ajax 文件的访问都会返回 200,但也有返回 302 的情况。其含义是“文件已移动”。但文件并未移动,不久之后恢复正常访问。
以下是访问日志的摘录,显示了一系列 200 响应,其中散布着一些 302,然后恢复 200。
108.221.39.97 - - [13/Jan/2023:10:07:52 -0600] "POST /ajax/set-var.php HTTP/2.0" 200 21 "https://www.rephunter.net/track-relationships.php?filter=clear" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
108.221.39.97 - - [13/Jan/2023:10:08:34 -0600] "POST /ajax/set-var.php HTTP/2.0" 200 21 "https://www.rephunter.net/track-relationships.php?filter=clear" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
108.221.39.97 - - [13/Jan/2023:10:09:56 -0600] "POST /ajax/set-var.php HTTP/2.0" 200 21 "https://www.rephunter.net/track-relationships.php?filter=clear" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
73.176.158.231 - - [13/Jan/2023:10:10:21 -0600] "POST /ajax/set-var.php HTTP/2.0" 200 21 "https://www.rephunter.net/track-relationships.php?filter=clear" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
74.73.226.238 - - [13/Jan/2023:10:15:07 -0600] "POST /ajax/set-var.php HTTP/2.0" 302 - "https://www.rephunter.net/track-relationships.php?filter=clear" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
184.178.239.162 - - [13/Jan/2023:10:15:18 -0600] "POST /ajax/set-var.php HTTP/2.0" 200 21 "https://www.rephunter.net/track-relationships.php?reply=tr-28560-80354" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.76"
74.73.226.238 - - [13/Jan/2023:10:15:20 -0600] "POST /ajax/set-var.php HTTP/2.0" 302 - "https://www.rephunter.net/track-relationships.php?filter=clear" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
24.144.188.195 - - [13/Jan/2023:10:15:22 -0600] "POST /ajax/set-var.php HTTP/2.0" 200 21 "https://www.rephunter.net/track-relationships.php?filter=clear" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"
74.73.226.238 - - [13/Jan/2023:10:15:28 -0600] "POST /ajax/set-var.php HTTP/2.0" 302 - "https://www.rephunter.net/track-relationships.php?filter=clear" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
74.73.226.238 - - [13/Jan/2023:10:15:34 -0600] "POST /ajax/set-var.php HTTP/2.0" 302 - "https://www.rephunter.net/track-relationships.php?filter=clear" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
74.73.226.238 - - [13/Jan/2023:10:15:37 -0600] "POST /ajax/set-var.php HTTP/2.0" 302 - "https://www.rephunter.net/track-relationships.php?filter=clear" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
74.73.226.238 - - [13/Jan/2023:10:15:49 -0600] "POST /ajax/set-var.php HTTP/2.0" 302 - "https://www.rephunter.net/track-relationships.php?filter=clear" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
72.38.12.208 - - [13/Jan/2023:10:15:54 -0600] "POST /ajax/set-var.php HTTP/2.0" 200 21 "https://www.rephunter.net/track-relationships.php?reply=tr-43850-7444" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.76"
74.73.226.238 - - [13/Jan/2023:10:16:07 -0600] "POST /ajax/set-var.php HTTP/2.0" 302 - "https://www.rephunter.net/track-relationships.php" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
74.73.226.238 - - [13/Jan/2023:10:16:19 -0600] "POST /ajax/set-var.php HTTP/2.0" 302 - "https://www.rephunter.net/track-relationships.php" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
108.221.39.97 - - [13/Jan/2023:10:17:23 -0600] "POST /ajax/set-var.php HTTP/2.0" 200 21 "https://www.rephunter.net/track-relationships.php?filter=clear" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
108.221.39.97 - - [13/Jan/2023:10:17:28 -0600] "POST /ajax/set-var.php HTTP/2.0" 200 21 "https://www.rephunter.net/track-relationships.php?filter=clear" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
72.38.12.208 - - [13/Jan/2023:10:17:49 -0600] "POST /ajax/set-var.php HTTP/2.0" 200 21 "https://www.rephunter.net/track-relationships.php?reply=tr-43850-7444" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.76"
108.221.39.97 - - [13/Jan/2023:10:17:58 -0600] "POST /ajax/set-var.php HTTP/2.0" 200 21 "https://www.rephunter.net/track-relationships.php?filter=clear" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
24.45.242.118 - - [13/Jan/2023:10:20:41 -0600] "POST /ajax/set-var.php HTTP/2.0" 200 21 "https://www.rephunter.net/track-relationships.php?filter=clear" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"
24.45.242.118 - - [13/Jan/2023:10:21:10 -0600] "POST /ajax/set-var.php HTTP/2.0" 200 21 "https://www.rephunter.net/track-relationships.php?filter=clear" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"
Run Code Online (Sandbox Code Playgroud)
编辑3:
我们有一个候选解决方案,其灵感来自 @ibrahim 对下面 Lajos Arpad 答案的评论。简而言之,向 ajax 调用添加重试功能,如https://forum.framework7.io/t/app-request-what-is-the-best-way-to-retry-an-ajax-request-using所示-app-request/4759,它似乎基于What's the best way to retry an AJAX request on failure using jQuery?。
在我们确认此修复有效后(这将需要一些“没有报告错误”的时间),我会将其标记为“答案”,@ibramim 是否应该发布他关于重试的评论作为答案。
您遇到的 AJAX 脚本问题通常可以正常工作,但对于某些(罕见)用户来说,有时会短暂找不到该文件。
使用隐身模式似乎可以解决这个问题。
解决方法有可能会同时出现,但不会导致 AJAX 恢复。因此,极少数情况下,该文件可能会在很短的时间内不可用(例如,有一个间歇性脚本重建/最小化程序会暂时删除该文件,以便将新版本移至其位置),并且用户会遇到以下情况:您提到的问题,但是,当他们尝试通过隐身模式访问它时,文件已经恢复,简而言之:隐身模式可能只与文件的恢复同时发生,但不会导致这种情况。
可以通过在问题发生时尝试隐身解决方法来反驳这一点,看看它是否有效,然后尝试在非隐身模式下查看它是否仍然不起作用(当然,在页面重新加载之后)。在答案的后半部分,我将假设隐身模式会导致用户的问题消失,并且不仅与问题的消失同时发生。
有些 cookie 是有问题的。例如,用户的 cookie 过期并且无法有效使用,但是当 cookie 仍然有效时页面已经开始加载,但是服务器会针对对文件的请求抛出文件移动错误,因为它被编程为仅为登录用户提供此请求。另外, /ajax/set-var.php可能会尝试加载现有会话中肯定存在的某个文件,但当前会话已被破坏,并且要访问的文件不再存在。
客户端缓存可能具有确切的文件名或路径,而文件已被重命名或移动。也有可能是在构建过程中请求该文件,此时正在写入文件并且不完整的文件已缓存到浏览器中。在您的情况下,这似乎不是问题,因为您有一个根据错误消息移动的 php 文件。
服务器端可能已经为您缓存了一些从那时起已被弃用/无效的信息。例如,为用户会话生成静态页面以避免重复相同的长请求逻辑。
sessionStorage当会话超时但页面仍在加载时,某些值很可能被存储并丢失,或者某些特定于会话的值被存储localStorage并不再有效。在这两种情况下,请求都是无效的,并且在服务器端会抛出一些错误,导致找不到文件。
这意味着在预期位置未找到某些文件。因此,为了修复它:
后端可能会出现很多问题,因此考虑到这一点,我的第一个方法是模拟“新请求”,就像尽可能在 cognito 中一样:
1- 创建一个函数来生成随机十六进制字符串,您将使用它将其作为查询字符串附加到您的请求中,以便它无法被缓存:
function genHex(n){
return Array.from({length:n}).reduce((ac,d) => ac += (Math.random() * 1e6 | 0).toString(16),"")
}
genHex(2)//'7ec05646dc'
Run Code Online (Sandbox Code Playgroud)
2- 添加请求标头以使缓存无效:
$.ajax({
asynch: false,//what the hell is this 'asynch'??
type: 'POST',
url: '/ajax/set-var.php?' + genHex(2),
headers:{
"Cache-control": "no-cache, no-store, must-revalidate",
"Pragma": "no-cache",
"Expires": "0"
},
Run Code Online (Sandbox Code Playgroud)
这个想法是,如果您的服务器出于某种原因忽略缓存控制标头,至少我们有随机查询参数来模拟类似的行为。尝试一下并告诉我,否则我会删除。
3-将所有内容包装在一个函数中,该函数在错误时会在设定的限制下自行执行。
function reAjax(limit = 2, firstCall = true, ...rest){
if(!limit){return}
$.ajax({
asynch: false,//what the hell is this 'asynch'??
type: 'POST',
url: `/ajax/set-var.php${firstCall ? "" : `?${genHex(2)}`}`,
headers:{
"Cache-control": "no-cache, no-store, must-revalidate",
"Pragma": "no-cache",
"Expires": "0"
},
error: (...rest) => reAjax(--limit, false, ...rest)
})
}
Run Code Online (Sandbox Code Playgroud)
该函数将在第一次不带查询参数(用于缓存清除)的情况下调用自身,并且它将继续在错误时调用缓存清除,直到limit命中为止。这里rest是jquery错误时传递的参数
PS:还要补充一点,如果你的后端是由第三方虚拟机控制的,有时他们会提出一个可以发出rate-limiting多少个POST请求。本质上,它们充当您和客户端之间的反向代理。因此请确保这些限制并非如此
| 归档时间: |
|
| 查看次数: |
697 次 |
| 最近记录: |