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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11017609/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 04:02:25  来源:igfitidea点击:

"undefined" randomly appended in 1% of requested urls on my website since 12 june 2012

javascriptbrowser

提问by colinux

Since 12 june 2012 11:20 TU, I see very weirds errors in my varnish/apache logs.

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

Sometimes, when an user has requested one page, several seconds later I see a similar request but the all string after the last / in the url has been replaced by "undefined".

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

Example: http://example.com/foo/bartriggers a http://example.com/foo/undefinedrequest.

示例: http://example.com/foo/bar触发http://example.com/foo/undefined请求。

Of course theses "undefined" pages does not exist and my 404 page is returned instead (which is a custom page with a standard layout, not a classic apache 404)

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

  • This happens with any pages (from the homepage to the deepest)
  • with various browsers, (mostly Chrome 19, but also firefox 3.5 to 12, IE 8/9...) but only 1% of the trafic.
  • The headers sent by these request are classic headers (and there is no ajax headers).
  • For a given ip, this seems occur randomly: sometimes at the first page visited, sometimes on a random page during the visit, sometimes several pages during the visit...
  • 任何页面都会发生这种情况(从主页到最深处)
  • 使用各种浏览器(主要是 Chrome 19,但也有 firefox 3.5 到 12,IE 8/9...)但只有 1% 的流量。
  • 这些请求发送的标头是经典标头(并且没有 ajax 标头)。
  • 对于给定的 ip,这似乎是随机发生的:有时在访问的第一个页面上,有时在访问期间的随机页面上,有时在访问期间的多个页面上......

Of course it looks like a javascript problem (I'm using jquery 1.7.2 hosted by google), but I've absolutely nothing changed in the js/html or the server configurationsince several days and I never saw this kind of error before. And of course, there is no such links in the html.

当然,它看起来像是一个 javascript 问题(我使用的是由 google 托管的 jquery 1.7.2),但是几天以来我在 js/html 或服务器配置中绝对没有任何变化,而且我以前从未见过这种错误. 当然,html 中没有这样的链接。

I also noticed some interesting facts:

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

  • the undefined requests are never found as referer of another pages, but instead the "real" pages were used as referer for the following request of the same IP (the user has the ability to use the classic menu on the 404 page)
  • I did not see any trace of these pages in Google Analytics, so I assume no javascript has been executed (tracker exists on all pages including 404)
  • nobody has contacted us about this, even when I invoked the problem in the social networks of the website
  • most of the users continue the visit after that
  • 未定义的请求永远不会被发现作为其他页面的引用,而是使用“真实”页面作为相同 IP 的以下请求的引用(用户可以使用 404 页面上的经典菜单)
  • 我在 Google Analytics 中没有看到这些页面的任何痕迹,所以我假设没有执行 javascript(跟踪器存在于所有页面上,包括 404)
  • 没有人就此与我们联系,即使我在网站的社交网络中提到了这个问题
  • 大多数用户在此之后继续访问

All theses facts make me think the problem occurs silently in the browers, probably triggered by a buggy add-on, antivirus, a browser bar or a crappy manufacturer soft integrated in browsers updated yesterday (but I didn't find any add-on released yesterday for chrome, firefox and IE).

所有这些事实让我认为问题在浏览器中默默发生,可能是由有问题的附加组件、防病毒软件、浏览器栏或昨天更新的浏览器中集成的蹩脚制造商软件触发的(但我没有发现任何附加组件已发布昨天适用于 chrome、firefox 和 IE)。

Is anyone here has noticed the same issue, or have a more complete explanation?

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

回答by Andrew Martinez

There is no simple straight answer.

没有简单直接的答案。

You are going to have to debug this and it is probably JavaScript due to the 'undefined' word in the URL. However it doesn't have to be AJAX, it could be JavaScript creating any URL that is automatically resolved by the browser (e.g. JavaScript that sets the src attribute on an image tag, setting a css-image attribute, etc). I use Firefoxwith Firebuginstalled most of the time, so my directions will be with that in mind.

您将不得不对此进行调试,并且由于 URL 中的“未定义”字样,它可能是 JavaScript。然而,它不一定是 AJAX,它可以是创建任何由浏览器自动解析的 URL 的 JavaScript(例如,在图像标签上设置 src 属性、设置 css-image 属性等的 JavaScript)。我大部分时间都使用安装了Firebug 的Firefox,所以我的指示将牢记这一点。

Firebug Initial Setup

Firebug 初始设置

Skip this if you already know how to use Firebug.

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

After the installs and restarting Firefox for Firebug, you are going to have to enable most of Firebug's 'panels'. To open Firebug there will be a little fire bug/insect looking thing in the top right corner of your browser or you can press F12. Click through the Firebug tabs 'Console', 'Script', 'Net' and enable them by opening them up and reading the panel's information. You might have to refresh the page to get them working properly.

安装并重新启动 Firefox for Firebug 后,您将不得不启用大部分 Firebug 的“面板”。要打开 Firebug,浏览器右上角会出现一个看起来像火虫/昆虫的小东西,或者您可以按 F12。单击 Firebug 选项卡“控制台”、“脚本”、“网络”,并通过打开它们并阅读面板信息来启用它们。您可能需要刷新页面才能使它们正常工作。

Debugging User Interaction

调试用户交互

Navigate to one of the pages that has the issue with Firebug open and the Net panel active. In the Net panel there will be a few options: 'Clear', 'Persist', 'All', 'Html', etc. Make sure ALL is selected. Don't do anything on the page and try not to mouse over anything on it. Look through the requests. The request for the invalid URL will be red and probably have a status of 404 Not Found (or similar).

导航到 Firebug 打开且网络面板处于活动状态时出现问题的页面之一。在 Net 面板中会有几个选项:'Clear'、'Persist'、'All'、'Html' 等。确保选择 ALL。不要在页面上做任何事情,尽量不要将鼠标悬停在页面上的任何内容上。查看请求。对无效 URL 的请求将是红色的,并且可能具有 404 Not Found(或类似状态)的状态。

See it on load? Skip to the next part.

看到它加载?跳到下一部分。

Don't see it on initial load? Start using your page and continue here.

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

Start clicking on every feature, mouse over everything, etc. Keep your eyes on the Net panel and watch for a requests that fail. You might have to be creative, but continue using your application till you see your browser make an invalid request. If the page makes many requests, feel free to hit the 'Clear' button on the top left of the Net panel to clear it up a bit.

开始单击每个功能,将鼠标悬停在所有内容上,等等。注意网络面板并注意失败的请求。您可能需要有创意,但继续使用您的应用程序,直到您看到浏览器发出无效请求。如果页面提出了很多请求,请随时点击网络面板左上角的“清除”按钮将其清除一点。

If you submit the page and see a failed request go out really quick but then lose it because the next page loads, enable persistence by clicking 'Persist' in the top left of the Net panel.

如果您提交页面并看到失败的请求非常快地发出,但由于下一页加载而丢失它,请通过单击网络面板左上角的“持久化”启用持久性。

Once it does, and it should, consider what you did to make that happen. See if you can make it happen again. After you figure out what user interaction is making it happen, dive into that code and start looking for things that are making invalid requests.

一旦它发生了,它应该考虑你做了什么来实现它。看看你能不能让它再次发生。在弄清楚是什么用户交互导致它发生后,深入研究该代码并开始寻找发出无效请求的内容。

You can use the Script tab to setup breakpoints in your JavaScript and step through them. Investigate event handlers done via $(elemment).bind/click/focus/etc or from old school event attributes like onclick=""/onfocus="" etc.

您可以使用“脚本”选项卡在 JavaScript 中设置断点并逐步执行。调查通过 $(element).bind/click/focus/etc 或旧式事件属性(如 onclick=""/onfocus="" 等)完成的事件处理程序。

If the request is happening as soon as the page loads

如果请求在页面加载后立即发生

This is going to be a little harder to peg down. You will need to go to the Script tab and start adding break points to every script that runs on load. You do this by clicking on the left side of the line of JavaScript.

这将更难固定。您将需要转到“脚本”选项卡并开始为每个加载时运行的脚本添加断点。您可以通过单击 JavaScript 行的左侧来执行此操作。

Reload your page and your break points should stop the browser from loading the page. Press the 'Continue' button on the script panel. Go to your net panel and see if your request was made, continue till it is found. You can use this to narrow down where the request is being made from by slowly adding more and more break points and then stepping into and out of functions.

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

What you are looking for in your code

您在代码中寻找的内容

Something that is similar to the following:

类似于以下内容:

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

var url = workingUrl + someObject.someProperty;

Keep in mind that someObject might be an object {}, an array [], or any of the internal browser types. The point is that a property will be accessed that doesn't exist.

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

I don't see any 404/red requests

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

Then whatever is causing it isn't being triggered by your tests. Try using more things. The point is you should be able to make the request happen somehow. You just don't know yet. It has to show up in the Net panel. The only time it won't is when you aren't doing whatever triggers it.

那么无论是什么导致它都不会被你的测试触发。尝试使用更多的东西。关键是您应该能够以某种方式使请求发生。你只是还不知道。它必须显示在网络面板中。唯一不会的时候是当你没有做任何触发它的事情时。

Conclusion

结论

There is no super easy way to peg down what exactly is going on. However using the methods I outlined you should be at least be able to get close. It is probably something you aren't even considering.

没有超级简单的方法来确定到底发生了什么。但是,使用我概述的方法,您至少应该能够接近。这可能是你甚至没有考虑的事情。

回答by Willy Barro

Based on this post, I reverse-engineered the "Complitly" Chrome Plugin/malware, and found that this extension is injecting an "improved autocomplete" feature that was throwing "undefined" requests at every site that has a input text field with NAME or ID of "search", "q" and many others.

根据这篇文章,我对“Complitly”Chrome 插件/恶意软件进行了逆向工程,发现该扩展程序正在注入“改进的自动完成”功能,该功能会在每个具有输入文本字段的站点上抛出“未定义”请求 NAME 或“搜索”、“q”和许多其他的 ID。

I found also that the enable.js file (one of complitly files) were checking a global variable called "suggestmeyes_loaded" to see if it's already loaded (like a Singleton). So, setting this variable to false disables the plugin.

我还发现 enable.js 文件(comlitly 文件之一)正在检查一个名为“suggestmeyes_loaded”的全局变量,以查看它是否已经加载(如单例)。因此,将此变量设置为 false 将禁用插件。

To disable the malware and stop "undefined" requests, apply this to every page with a search field on your site:

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

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

This malware also redirects your users to a "searchcompletion.com" site, sometimes showing competitors ADS. So, it should be taken seriously.

此恶意软件还会将您的用户重定向到“searchcompletion.com”站点,有时会显示竞争对手的 ADS。所以,应该认真对待。

回答by Ja?ck

You have correctly established that the undefinedrelates to a JavaScript problem and if your site users haven't complained about seeing error pages, you could check the following.

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

If JavaScript is used to set or change image locations, it sometimes happens that an undefinedmakes its way into the URI.

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

When that happens, the browser will happily try to load the image (no AJAX headers), but it will leave hints: it sets a particular Accept:header; instead of text/html, text/xml, ...it will use image/jpeg, image/png, ....

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

Once such a header is confirmed, you have narrowed down the problem to images only. Finding the root cause will possibly take some time though :)

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

Update

更新

To help debugging you could override $.fn.attr()and invoke the debugger when something is being assigned to undefined. Something like this:

为了帮助调试,您可以$.fn.attr()在将某些内容分配给 undefined 时覆盖并调用调试器。像这样的东西:

?(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));

回答by Chris Sattinger

Some facts that have been established, especially in this thread: http://productforums.google.com/forum/#!msg/chrome/G1snYHaHSOc/p8RLCohxz2kJ

已经确定的一些事实,尤其是在此线程中:http: //productforums.google.com/forum/#!msg/chrome/G1snYHaHSOc/p8RLCohxz2kJ

it happens on pages that have no javascript at all. this proves that it is not an on-page programming error

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

the user is unaware of the issue and continues to browse quite happily.

用户不知道该问题并继续愉快地浏览。

it happens a few seconds after the person visits the page.

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

it doesn't happen to everybody.

它不会发生在每个人身上。

happens on multiple browsers (Chrome, IE, Firefox, Mobile Safari, Opera)

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

happens on multiple operating systems (Linux, Android, NT)

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

happens on multiple web servers (IIS, Nginx, Apache)

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

I have one case of googlebot following the link and claiming the same referrer. They may just be trying to be clever and the browser communicated it to the mothership who then set out a bot to investigate.

我有一个 googlebot 跟踪链接并声明相同的引用者的案例。他们可能只是想变得聪明,浏览器将其传达给母舰,然后母舰设置了一个机器人进行调查。

I am fairly convinced by the proposal that it is caused by plugins. Complitly is one, but that doesn't support Opera. There many be others.

我相当相信它是由插件引起的。Complitly 是其中之一,但它不支持 Opera。还有很多其他的。

Though the mobile browsers weigh against the plugin theory.

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

Sysadmins have reported a major drop off by adding some javascript on the page to trick Complitly into thinking it is already initialized.

系统管理员报告说,通过在页面上添加一些 javascript 以欺骗 Complitly 认为它已经初始化,这是一个重大下降。

Here's my solution for nginx:

这是我的 nginx 解决方案:

location ~ undefined/?$  {
  return 204;
}

This returns "yeah okay, but no content for you".

这将返回“是的,好的,但没有适合您的内容”。

If you are on website.com/some/page and you (somehow) navigate to website.com/some/page/undefined the browser will show the URL as changed but will not even do a page reload. The previous page will stay as it was in the window.

如果您在 website.com/some/page 并且您(以某种方式)导航到 website.com/some/page/undefined 浏览器会将 URL 显示为已更改,但甚至不会重新加载页面。上一页将保持在窗口中的原样。

If for some reason this is something experienced by users then they will have a clean noop experience and it will not disturb whatever they were doing.

如果由于某种原因这是用户所经历的事情,那么他们将拥有干净的 noop 体验,并且不会打扰他们正在做的任何事情。

回答by Art

This sounds like a race condition where a variable is not getting properly initialized before getting used. Considering this is not an AJAX issue according to your comments, there will be a couple of ways of figuring this out, listed below.

这听起来像是一个竞争条件,其中变量在使用之前没有正确初始化。根据您的评论,考虑到这不是 AJAX 问题,下面列出了几种解决方法。

Hookup a Javascript exception Logger: this will help you catch just about all random javascript exceptions in your log. Most of the time programmatic errors will bubble up here. Put it before any scripts. You will need to catch these on the server and print them to your logs for analysis later. This is your first line of defense. Here is an example:

连接一个 Javascript 异常记录器:这将帮助您捕获日志中几乎所有随机的 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);
};

Search for window.location: for each of these instances you should add logging or check for undefined concats/appenders to your window.location. For example:

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

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

or the slightly cleaner:

或稍微清洁一点:

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
} 

If you are interested in getting stacktraces at this stage take a look at: https://github.com/eriwen/javascript-stacktrace

如果您有兴趣在此阶段获取堆栈跟踪,请查看:https: //github.com/eriwen/javascript-stacktrace

Grab all unhandled undefined links: Besides window.location The only thing left are the DOM links themselves. The third step is to check all unhandeled DOM links for your invalid URL pattern (you can attach this right after jQuery finishes loading, earlier better):

抓取所有未处理的未定义链接:除了 window.location 唯一剩下的就是 DOM 链接本身。第三步是检查所有未处理的 DOM 链接是否存在无效的 URL 模式(您可以在 jQuery 完成加载后立即附加它,越早越好):

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

Hope this is helpful. Happy debugging.

希望这是有帮助的。调试愉快。

回答by Sean

I'm wondering if this might be an adblocker issue. When I search through the logs by IP address it appears that every request by a particular user to /folder/page.html is followed by a request to /folder/undefined

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

回答by Joseph Coco

I don't know if this helps, but my website is replacing one particular *.webp image file with undefined after it's loaded in multiple browsers. Is your site hosting webp images?

我不知道这是否有帮助,但我的网站在多个浏览器中加载后将一个特定的 *.webp 图像文件替换为 undefined。您的网站是否托管 webp 图像?

回答by Iwazaru

I had a similar problem (but with /null404 errors in the console) that @andrew-martinez's answer helped me to resolve.

我有一个类似的问题(但/null控制台中有404 错误)@andrew-martinez 的回答帮助我解决了这个问题。

Turns out that I was using imgtags with an empty srcfield:

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

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

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

My idea was to prevent browser from loading the image at page load to manually load later by setting the src attribute from the data-src attribute with javascript (lazy loading). But when combined with iDangerous Swiper, that method caused the error.

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