自2012年6月12日以来,“未定义”随机附加在我网站上1% 的请求网址上

自2012年6月12日11:20 TU 以来,我在清漆/apache 日志中看到了非常奇怪的错误。

有时候,当一个用户请求一个页面时,几秒钟后我看到一个类似的请求,但是 url 中最后一个/之后的所有字符串都被“未定义”替换了。

例如: Http://example.com/foo/bar 触发 翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳 http://example.com/foo/undefined请求。

当然,这些“未定义”页面并不存在,而是返回我的404页面(这是一个具有标准布局的自定义页面,而不是经典的 apache 404)

  • 这种情况发生在任何页面(从主页到最深处)
  • 不同的浏览器,(大部分是 Chrome 19,但也有 Firefox 3.5到12,IE 8/9...) ,但只有1% 的流量。
  • 这些请求发送的头是经典的头(没有 ajax 头)。
  • 对于给定的 ip,这似乎是随机发生的: 有时在访问的第一个页面,有时在访问期间在一个随机页面,有时在访问期间几页..。

当然,它看起来像是一个 javascript 问题(我使用的是由 google 托管的 jquery 1.7.2) ,但是 我在 js/html 或服务器配置中绝对没有任何更改已经出现了好几天了,我以前从来没有看到过这样的错误。当然,在 html 中没有这样的链接。

我还注意到一些有趣的事实:

  • 未定义的请求从未被发现作为另一个页面的引用,而是“实际”页面被用作同一 IP 的下列请求的引用(用户可以使用404页面上的经典菜单)
  • 在 GoogleAnalytics 中我没有看到这些页面的任何痕迹,所以我假设没有执行任何 javascript (跟踪器存在于包括404在内的所有页面上)
  • 即使我在网站的社交网络上提到这个问题,也没有人联系我们
  • 大多数用户在那之后继续访问

所有这些事实让我认为,问题在浏览器中悄无声息地发生,可能是由一个漏洞插件、杀毒软件、浏览器栏或者一个糟糕的制造商软件集成在昨天更新的浏览器中引发的(但我昨天没有发现任何针对 chrome、 firefox 和 IE 的插件)。

这里有人注意到同样的问题,或者有更完整的解释吗?

30191 次浏览

您已经正确地确定了 undefined与 JavaScript 问题有关,如果您的站点用户没有抱怨看到错误页面,您可以检查以下内容。

如果使用 JavaScript 设置或更改图像位置,有时会发生 undefined进入 URI 的情况。

当这种情况发生时,浏览器会很高兴地尝试加载图像(没有 AJAX 头) ,但它会留下提示: 它设置一个特定的 Accept:头; 它将使用 image/jpeg, image/png, ...而不是 text/html, text/xml, ...

一旦确认了这样的标题,您就将问题缩小到只有图像。不过,找到根本原因可能需要一些时间:)

更新

为了帮助调试,您可以重写 $.fn.attr(),并在将某些内容分配给未定义的内容时调用调试器。就像这样:

​(function($, undefined) {
var $attr = $.fn.attr;


$.fn.attr = function(attributeName, value) {
var v = attributeName === 'src' ? value : attributeName.src;


if (v === 'undefined') {
alert("Setting src to undefined");
}


return $attr(attributeName, value);
}
}(jQuery));

没有简单直接的答案。

你将不得不调试这个,它可能是 JavaScript,由于’未定义的’字在 URL。然而它不一定是 AJAX,它可以是 JavaScript 创建任何由浏览器自动解析的 URL (例如,在图像标签上设置 src 属性的 JavaScript,设置 css-image 属性等)。我使用 火狐纵火犯安装的大部分时间,所以我的方向将与此铭记在心。

Firebug 初始设置

如果您已经知道如何使用 Firebug,请跳过此步骤。

在为 Firebug 安装和重新启动 Firefox 之后,你需要启用 Firebug 的大部分“面板”。要打开 Firebug,你的浏览器右上角会出现一个小小的火虫/昆虫图案,或者你可以按 F12。点击 Firebug 标签“ Console”、“ Script”、“ Net”,打开并阅读面板信息,启用它们。您可能需要刷新页面才能使它们正常工作。

调试用户交互

导航到 Firebug 打开并激活 Net 面板时出现问题的页面之一。在 Net 面板中有几个选项: “ Clear”、“ Perst”、“ All”、“ Html”等等。确保选择了 ALL。不要在页面上做任何事情,尽量不要将鼠标移到页面上的任何东西上。看看这些请求。对无效 URL 的请求将是红色的,并且可能具有404 Not Found (或类似的)状态。

加载时看到了吗? 跳到下一部分。

在初始加载时没有看到它? 开始使用您的页面并在这里继续。

开始点击每一个功能,鼠标在一切等。保持你的眼睛在网络面板和观察一个请求失败。您可能必须要有创造性,但是继续使用您的应用程序,直到您看到您的浏览器发出无效的请求。如果页面提出了许多请求,可以随意点击 Net 面板左上角的“ Clear”按钮来清理一下。

如果您提交了页面,并且看到一个失败的请求非常快地发出,但是因为下一个页面加载而丢失了它,那么通过单击 Net 面板左上角的“ Perst”来启用持久性。

一旦发生了,也应该发生了,想想你是怎么做到的。看看你能不能让它再次发生。在您弄清楚是什么用户交互使其发生之后,请深入研究该代码并开始查找发出无效请求的内容。

您可以使用 Script 选项卡在 JavaScript 中设置断点并逐步通过它们。调查通过 $(元素)完成的事件处理程序。Bind/click/focus/etc 或来自旧学校的事件属性,如 onclick = “”/onfocus = “”等。

如果页面加载后立即发生请求,则为

这可能有点难以控制。您将需要转到 Script 选项卡,并开始向每个在加载时运行的脚本添加断点。您可以通过单击 JavaScript 行的左侧来实现这一点。

重新加载页面,断点应该会阻止浏览器加载页面。按脚本面板上的“继续”按钮。进入你的网络面板,看看你的请求是否被提出,继续,直到找到。您可以使用这个函数,通过缓慢地添加越来越多的断点,然后逐步进入和退出函数,来缩小发出请求的位置。

在代码中查找的内容

类似于下列事物的东西:

var url = workingUrl + someObject['someProperty'];


var url = workingUrl + someObject.someProperty;

请记住,somObject 可能是对象 {}、数组 []或任何内部浏览器类型。关键是,将访问一个不存在的属性。

我没看到任何404/红色请求

那么不管是什么引起的,都不是你的测试触发的。试着用更多的东西。关键是您应该能够以某种方式使请求发生。你只是还不知道。它必须显示在网络面板上。只有当你不做任何触发它的事情时,它才不会发生。

结论

没有超级简单的方法可以确定到底发生了什么。然而,使用我概述的方法,你至少应该能够接近。你可能根本就没考虑过这个问题。

这听起来像是一个竞争条件,其中变量在使用之前没有得到正确的初始化。考虑到这不是一个 AJAX 问题根据您的意见,将有一对夫妇的方式来解决这个问题,下面列出。

挂接 Javascript 异常 Logger : 这将帮助您在日志中捕获几乎所有随机的 Javascript 异常。大多数时候,程序错误都会在这里冒出来。把它放在任何脚本之前。您需要在服务器上捕获这些内容,并将它们打印到您的日志中以便稍后进行分析。这是你的第一道防线。这里有一个例子:

window.onerror = function(m,f,l) {
var e = window.encodeURIComponent;
new Image().src = "/jslog?msg=" + e(m) + "&filename=" + e(f) + "&line=" + e(l) + "&url=" + e(window.location.href);
};

搜索 window.location : 对于这些实例中的每一个,您都应该向 window.location 添加日志记录或检查未定义的 concats/appender。例如:

function myCode(loc) {
// window.location.href = loc; // old
typeof loc === 'undefined' && window.onerror(...); //new
window.location.href = loc; //new
}

或者稍微干净一点:

window.setLocation = function(url) {
/undefined/.test(url) ?
window.onerror(...) : window.location.href = url;
}


function myCode(loc) {
//window.location.href = loc; //old
window.setLocation(loc); //new
}

如果您对在这个阶段获得堆栈跟踪感兴趣,请看一下: https://github.com/eriwen/javascript-stacktrace

抓取所有未处理的未定义链接 : 除了 window.location 之外,剩下的只有 DOM 链接本身。第三步是检查所有未处理的 DOM 链接是否有无效的 URL 模式(您可以在 jQuery 完成加载后立即附加此链接,最好在早些时候附加) :

$("body").on("click", "a[href$='undefined']", function() {
window.onerror('Bad link: ' + $(this).html()); //alert home base
});

希望这对你有帮助,调试愉快。

我在想这是不是广告拦截器的问题。当我按 IP 地址搜索日志时,似乎特定用户对/file/page.html 的每个请求后面都跟着对/file/unDefinition 的请求

基于这个 邮寄,我逆向设计了“完整的”Chrome 插件/恶意软件,发现这个扩展插件注入了一个“改进的自动完成”功能,在每个有 NAME 或 ID 为“搜索”、“ q”和许多其他输入文本字段的网站上抛出“未定义的”请求。

我还发现,able.js 文件(一个完整的文件)正在检查一个名为“ Sugestmeyes _ load”的全局变量,以查看它是否已经加载(如 Singleton)。因此,将这个变量设置为 false 将禁用该插件。

要禁用恶意软件并停止“未定义”请求,请将此应用于您网站上每个带有搜索字段的页面:

<script type="text/javascript">
window.suggestmeyes_loaded = true;
</script>

这个恶意软件还会将你的用户重定向到一个“ searchcompletion.com”网站,有时会显示竞争对手的广告系统。

已经建立的一些事实,特别是在这个线程中: http://productforums.google.com/forum/#!msg/chrome/G1snYHaHSOc/p8RLCohxz2kJ

它发生在根本没有 javascript 的页面上。 这证明它不是页面编程错误

用户没有意识到这个问题,继续愉快地浏览。

它发生在访问者访问页面后几秒钟。

不是每个人都会这样。

发生在多个浏览器上(Chrome,IE,Firefox,Mobile Safari,Opera)

发生在多个操作系统(Linux、 Android、 NT)上

发生在多个 web 服务器(IIS、 Nginx、 Apache)上

我有一个情况下,谷歌机器人下面的链接,并声称同一个引用。他们可能只是想变得更聪明,浏览器将其传达给母舰,母舰随后派出一个机器人进行调查。

我相当相信的建议,它是由插件造成的。完整是其中之一,但它不支持 Opera。还有很多其他人。

尽管移动浏览器与插件理论相左。

系统管理员已经报告了一个主要的下降,通过在页面上添加一些 javascript 来欺骗 Compitly 认为它已经初始化了。

下面是我对 nginx 的解决方案:

location ~ undefined/?$  {
return 204;
}

这将返回“ yeah okay,but no content for you”。

如果你使用 website.com/some/page website.com/some/page/undefined ,浏览器会显示已更改的 URL,但是不会重新加载页面。前一页将保持在窗口中的样子。

如果出于某种原因,这是一些经验的用户,那么他们将有一个干净的 noop 体验,它将不会干扰他们正在做什么。

我不知道这是否有帮助,但我的网站正在取代一个特别的 * 。Webp 图像文件在多个浏览器中加载后未定义。你的网站是否有网页图片?

我也遇到过类似的问题(但是控制台中出现了 /null404错误) ,@andrew-martinez 的回答帮助我解决了这个问题。

原来我使用的是带有空 src字段的 img标签:

<img src="" alt="My image" data-src="/images/my-image.jpg">

我的想法是通过使用 javascript (延迟加载)设置 data-src 属性中的 src 属性,防止浏览器在页面加载时加载图像,以便以后手动加载。但是当与 iCrisis Swiper 结合使用时,该方法会导致错误。