Lỗi mã script khó hiểu. báo cáo bằng Javascript trong Chrome và Firefox


199

Tôi có một tập lệnh phát hiện lỗi Javascript trên trang web của mình và gửi chúng đến phần phụ trợ của tôi để báo cáo. Nó báo cáo lỗi đầu tiên gặp phải, số dòng được cho là và thời gian.

EDIT để bao gồm doctype:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" xmlns:fb="http://www.facebook.com/2008/fbml">

...

<script type="text/javascript">
//<![CDATA[
// for debugging javascript!
(function(window){
    window.onerror = function(msg, url, ln) {
        //transform errors
        if (typeof(msg) === 'object' && msg.srcElement && msg.target) {
            if(msg.srcElement == '[object HTMLScriptElement]' && msg.target == '[object HTMLScriptElement]'){
                msg = 'Error loading script';
            }else{
                msg = 'Event Error - target:' + msg.target + ' srcElement:' + msg.srcElement;
            }
        }

        msg = msg.toString();

        //ignore errors
        if(msg.indexOf("Location.toString") > -1){
            return;
        }
        if(msg.indexOf("Error loading script") > -1){
            return;
        }

        //report errors
        window.onerror = function(){};
        (new Image()).src = "/jserror.php?msg=" + encodeURIComponent(msg) + "&url=" + encodeURIComponent(url || document.location.toString().replace(/#.*$/, "")) + "&ln=" + parseInt(ln || 0) + "&r=" + (+new Date());
    };
})(window);
//]]>
</script>

Do tập lệnh này, tôi nhận thức sâu sắc về bất kỳ lỗi javascript nào đang xảy ra trên trang web của mình. Một trong những người phạm tội lớn nhất là "Lỗi Script". trên dòng 0. trong Chrome 10+ và Firefox 3+. Lỗi này không tồn tại (hoặc có thể được gọi là cái gì khác?) Trong Internet Explorer.

Sửa chữa (23/5/2013): Lỗi "Lỗi Script, Dòng 0" này hiện đang hiển thị trong IE7 và có thể các phiên bản IE khác. Có thể là kết quả của một bản vá bảo mật IE gần đây vì hành vi này trước đây không tồn tại.

Có ai có ý tưởng gì về lỗi này có nghĩa là gì hoặc nguyên nhân gây ra nó không? Nó xảy ra với khoảng 0,25% tổng số trang tải của tôi và chiếm một nửa số lỗi được báo cáo.


Doctype của bạn là gì? Nếu bạn không khai báo loại tài liệu XHTML, thì bạn không cần CDATA, đó có thể là lý do tại sao có lỗi tập lệnh.
James

Tôi đánh giá cao sự giúp đỡ ... Đã thêm tài liệu: XHTML. Ngoài ra, mặc dù, chỉ xảy ra trên 0,25% tải trọng trang ... Tôi sẽ nghĩ đó là một cái gì đó kỳ lạ hơn.
Mike Sherov

3
@jayp: Chỉ cần đề cập. XHTML doctype vẫn là trình phân tích cú pháp HTML. Bạn phải gửi nội dung application/xhtml+xmlđể chạy nó trong trình phân tích cú pháp XHTML (như đặc tả XHTML nói). Có rất nhiều nội dung tuyên bố là XHTML, nhưng gửi tài liệu HTML bình thường. Do cách người tạo nội dung sử dụng XHTML không chính xác, các trình duyệt đã quyết định chỉ sử dụng trình phân tích cú pháp XML trên application/xhtml+xml(đó là trình phân tích cú pháp thực sự nghiêm ngặt). Các hixie.ch/advocacy/xhtmlwebdevout.net/articles/beware-of-xhtml nói tại sao không sử dụng HTML parser với XHTML.
Konrad Borowski

11
Thở dài ... vì tình yêu của chúa, bất cứ ai đọc nó, xin vui lòng làm cho thông báo lỗi của bạn giải thích chính xác những gì đã sai! Bằng cách tiết kiệm cho mình 30 giây nỗ lực để viết nó, bạn đang lãng phí thế giới nhiều năm!
Roman Starkov

1
Bạn đang bỏ qua Lỗi Đang tải Lỗi Script. Tại sao? Họ có an toàn để bỏ qua?
đoạn đường nối

Câu trả lời:


261

"Lỗi script." xảy ra trong Firefox, Safari và Chrome khi một ngoại lệ vi phạm chính sách cùng nguồn gốc của trình duyệt - tức là khi xảy ra lỗi trong tập lệnh được lưu trữ trên một tên miền không phải là miền của trang hiện tại.

Hành vi này là có chủ ý, để ngăn chặn các tập lệnh rò rỉ thông tin ra các miền bên ngoài. Để biết ví dụ về lý do tại sao điều này là cần thiết, hãy tưởng tượng vô tình truy cập evilsite.com, phục vụ lên một trang với <script src="yourbank.com/index.html">. (vâng, chúng tôi đang chỉ thẻ script đó ở html, không phải JS). Điều này sẽ dẫn đến lỗi tập lệnh, nhưng lỗi này rất thú vị vì nó có thể cho chúng tôi biết bạn có đăng nhập hay không. Nếu bạn đã đăng nhập, lỗi có thể xảy ra 'Welcome Fred...' is undefined, trong khi nếu bạn không đăng nhập 'Please Login ...' is undefined. Một cái gì đó dọc theo những dòng.

Nếu evilsite.com thực hiện điều này cho 20 tổ chức ngân hàng hàng đầu, họ sẽ có một ý tưởng khá hay về việc bạn truy cập trang web ngân hàng nào và có thể cung cấp trang lừa đảo được nhắm mục tiêu nhiều hơn. (Tất nhiên đây chỉ là một ví dụ. Nhưng nó minh họa tại sao các trình duyệt không nên cho phép bất kỳ dữ liệu nào vượt qua ranh giới miền.)

Tôi đã thử nghiệm điều này trong các phiên bản Safari, Chrome và Firefox mới nhất - tất cả đều làm điều này. IE9 không - nó xử lý các ngoại lệ nguồn gốc x giống như các trường hợp cùng nguồn gốc. (Và Opera không hỗ trợ onerror.)

Từ miệng ngựa: Nguồn WebKit kiểm tra nguồn gốc khi chuyển ngoại lệ cho onerror (). Và nguồn Firefox kiểm tra .

CẬP NHẬT (21/10/11) : Lỗi Firefox theo dõi vấn đề này bao gồm một liên kết đến bài đăng trên blog đã truyền cảm hứng cho hành vi này.

CẬP NHẬT (12/2/14) : Bây giờ bạn có thể bật báo cáo lỗi tên miền đầy đủ trên một số trình duyệt bằng cách chỉ định một crossoriginthuộc tính trên thẻ tập lệnh và yêu cầu máy chủ gửi tiêu đề phản hồi HTTP CORS thích hợp .


3
Cảm ơn vì điều đó. Tôi muốn một chút làm rõ. Tôi thấy các thông báo lỗi chi tiết từ các tập lệnh mà tôi đưa vào trang của mình mọi lúc. Ví dụ: nếu tôi bao gồm jQuery từ cdn của google và sử dụng nó để thao tác một phần tử không tồn tại trên trang của tôi, tôi nhận được một trình khởi chạy trỏ đến CDN của google. Bạn đang nói rằng "Lỗi Script." đang xảy ra bởi vì các kịch bản từ xa đang ném ngoại lệ?
Mike Sherov

150
Bạn có thể nghĩ ai đó sẽ có ý thức nói "Một kịch bản từ xa đã đưa ra một lỗi bị ẩn do chính sách cùng nguồn gốc", thay vì để bạn tự hỏi điều gì đã xảy ra, eh? ...
Roman Starkov

3
@broofa Điều này có nghĩa là tôi sẽ trở nên tốt hơn ngoại trừ nếu tôi lưu trữ jquery trên miền của mình thay vì sử dụng CDN của Google?
Paul Biggar

6
Cập nhật nhỏ. Nó cũng xảy ra cục bộ khi một trang được tải qua tệp: // và tập lệnh được chạy qua eval (). Trường hợp sử dụng nhỏ nhưng vẫn còn :)
Willem Mulder

6
Sau một số điều tra, tôi nhận thấy rằng Script Error.cũng xảy ra nếu người dùng đã cài đặt Tiện ích mở rộng Safari (có thể giống với Trình cắm Firefox) có mã JavaScript bị lỗi
Alex Hoppen

49

Một bản cập nhật cho những người sẽ vấp phải câu hỏi này trong tương lai: broofa đã đúng với câu trả lời và không có cách giải quyết nào cho vấn đề này.

Rõ ràng là những người khác vấp phải giới hạn này và một số lỗi yêu cầu sửa lỗi đã được gửi cho Firefox: Bug 69602 và cho WebKit: Bug 70574

Tin vui là lỗi đã được khắc phục cho Firefox với việc phát hành Firefox 13. Đây là cách bạn sử dụng nó:

<script src="http://somremotesite.example/script.js" crossorigin>

crossorigintương đương crossorigin=anonymousvà yêu cầu trình duyệt thực hiện tìm nạp CORS của tập lệnh mà không gửi thông tin đăng nhập.

Bạn phải đảm bảo rằng tập lệnh được gửi với Access-Control-Allow-Origingiá trị tiêu đề HTTP phù hợp với miền yêu cầu, ví dụ:

Access-Control-Allow-Origin: http://myhomesite.example
Access-Control-Allow-Origin: *

nếu không trình duyệt sẽ hủy tải tập lệnh .

Đối với Apache:

Header set Access-Control-Allow-Origin "*"

(Và xem ví dụ CORS cho các máy chủ web khác .)

Nếu bạn đang gửi tập lệnh trong PHP:

header('Access-Control-Allow-Origin', 'http://myhomesite.example');

Tôi đã thử nghiệm điều này và nó hoạt động như mong đợi. tất cả các lỗi từ script.js sẽ được window.onerrorxử lý bắt bằng các chi tiết thông báo, tệp và dòng.

Lỗi WebKit chưa được sửa, nhưng một bản vá đã được đề xuất (và sử dụng cùng một giải pháp). Hy vọng bản sửa lỗi sẽ sớm được phát hành.

Thông tin thêm về CORS tại đây: http://enable-cors.org/



1
Re webkit. Nếu bạn muốn nói điều này, có vẻ như nó đã được giải quyết ngay bây giờ: bug.webkit.org/show_orms.cgi?id=70574
UpTheCalet

3
Giả sử chúng tôi muốn theo dõi các lỗi JS trong mysite.com/index.php, bao gồm tệp JS từ bên ngoài (ví dụ: máy chủ của nhà cung cấp API apiprovider.com/api.js); trong trường hợp này, chúng tôi không có quyền truy cập vào máy chủ đó vì vậy chúng tôi không thể thêm tiêu đề "Kiểm soát truy cập-Cho phép-Xuất xứ". Có cách nào để nhận thông báo lỗi có nguồn gốc từ api.js không?
Eugenio

23

Điều này mất khá nhiều để tìm ra.

Chúng tôi đã thực hiện một loạt các công cụ để thử và giải quyết nó, bao gồm thực hiện những việc như đưa cơ thể tài liệu WHOLE trở lại máy chủ của chúng tôi thông qua Ajax để thử và tìm ra nó.

Tôi vẫn không chắc chắn điều gì gây ra "Lỗi Script". (với BTW thời kỳ, đó là cách nó xuất hiện trong trình ghi nhật ký Ajax của chúng tôi) trong Firefox, nhưng trong Chrome, chúng tôi đã có thể thu hẹp nó xuống ...

Trống cuộn...

Tính năng tự động dịch của Google Chrome.

Nhiều người nói tiếng Anh có thể thậm chí không biết về tính năng này, nhưng để kiểm tra nó, tôi đoán truy cập một trang web không phải tiếng Anh bằng Chrome. Hoặc tốt hơn nữa, nếu bạn khai thác các tùy chọn Chrome, sẽ có một điểm để thay đổi ngôn ngữ trình duyệt. Thay đổi nó thành một cái gì đó không phải tiếng Anh, khởi động lại trình duyệt và truy cập một trang web tiếng Anh.

Bạn nên đặt thanh ở đầu hỏi xem bạn có muốn Chrome dịch trang cho bạn không.

Trong trường hợp của chúng tôi, dù sao đi nữa, người dịch đã gây ra sự cố do nó đưa thẻ script vào thân tài liệu của bạn và (đoán ở đây) sử dụng một số hệ thống dựa trên JS để gửi nội dung đến các máy chủ của Google và yêu cầu họ dịch nó.

Mặc dù lỗi trong bảng điều khiển là Không được kiểm tra, nhưng thông báo đang được gửi tới window.onerror là "Lỗi Script."

Dù sao, có một cách chữa trị.

http://googlewebmastercentral.blogspot.com/2007/12/answering-more-p phổ biến-pick-meta-tags.html

<meta name="google" content="notranslate"/>

Điều này sẽ làm 2 việc (theo như chúng tôi biết, có thể nhiều hơn?):

a) Vô hiệu hóa thanh dịch từ bật lên trong Chrome.

b) Vô hiệu hóa dịch trang thông qua translate.google.com.

Trong tình huống của chúng tôi, dù sao đi nữa, điều này đã giải quyết MỘT TẤN của "Lỗi tập lệnh" này. những vấn đề chúng tôi đã gặp phải.

Xin lỗi vì lỗi chính tả trong bài đăng này, tôi vẫn đang ở chế độ không phải tiếng Anh trong Chrome khi viết bài này và trình kiểm tra chính tả không được đặt thành tiếng Anh;) Thời gian để quay lại.

Thưởng thức!


4
Lý do trực tiếp có lẽ là tập lệnh dịch được chạy từ một tên miền khác sau đó là trang web và onerror(ít nhất là trong Firefox) chỉ nói "Lỗi tập lệnh" trong trường hợp như vậy.
Tgr

10

Do% thấp, bạn có thể cho rằng họ không phải là người dùng bình thường. Có thể là người dùng với usercripts, bookmarklets hoặc thậm chí có thể chỉ gây rối với bảng điều khiển trên trang web của bạn. Có toàn bộ HTML của một trang nơi nó xảy ra có thể giúp kiểm tra lý thuyết này. Cũng như lỗi hoàn toàn. Nó sẽ cung cấp cho bạn một url, nó luôn luôn giống nhau? Là dòng thực sự 0 hoặc chỉ không xác định?

Tôi không nghĩ rằng việc thiết lập các giá trị mặc định trong onerror của bạn là một ý tưởng hay và 0 có lẽ xuất phát từ parseInt(ln || 0)khi lỗi không thực sự xuất hiện trên trang (xem ví dụ ở trên).

Thêm một câu hỏi để xem liệu dòng được biết trong JavaScript có bỏ qua các lỗi đó không (vì có thể chúng không xuất phát từ mã của riêng bạn) hoặc trong mã phía máy chủ để xử lý chúng một cách riêng biệt, imo, sẽ tốt hơn .

=== EDIT === Đã đến: http://www.xavierm02.net/AZE/ Cài đặt tệp user.js (Tôi đã làm nó trên Chrome nhưng nó cũng hoạt động trên Firefox). Sau đó mở trang html trên cùng một trình duyệt. Nó sẽ hiển thị cho bạn lỗi (Tôi chỉ thay đổi bản báo cáo đó đến máy chủ, nó sẽ ghi nó trên trang). Với 0 là số dòng.


URL được phân phối đồng đều giữa các trang trên trang web của tôi. Tôi cũng đoán bookmarklets hoặc thậm chí các tiện ích mở rộng hoặc chủ đề, xem xét nó là FF và chrome. Tuy nhiên, tôi rất muốn có thể repro chính xác thông báo lỗi này trước khi bỏ qua nó một cách an toàn.
Mike Sherov

Thay thế dòng của bạn bằng (new Image()).src = "/jserror.php?msg=" + encodeURIComponent(msg) + "&url=" + encodeURIComponent(url) + "&ln=" + parseInt(ln) + "&r=" + (+new Date());và có thể bạn sẽ không thấy url (vì đó là tiện ích mở rộng hoặc thứ gì đó cục bộ để trình duyệt không hiển thị cho bạn) và không có số dòng.
xavierm02

Và btw, bạn nên lấy dấu thời gian với máy chủ của mình hơn là với JS (và thậm chí có thể chỉ lấy phiên bản, thay vì dấu thời gian).
xavierm02

1
Trong thực tế, JS chỉ nên gửi dữ liệu thô và PHP sẽ quan tâm đến việc bỏ qua các lỗi tải, v.v.
xavierm02

Tôi thực hiện một số xử lý về phía JS vì tôi chỉ muốn báo cáo lỗi có liên quan FIRST, vì vậy tôi gán lại chức năng onerror trở lại không có gì sau khi có lỗi thực sự xảy ra. Điều này cũng ngăn các lỗi xảy ra trong các vòng lặp từ máy chủ của tôi .
Mike Sherov

3

Tôi đã có một vấn đề tương tự: tập lệnh của tôi được phục vụ bởi một tên miền phụ và thuộc cùng một hạn chế nguồn gốc. Tuy nhiên, tôi đã giải quyết điều này bằng cách:

1) thêm mọi thẻ script như thế này:

<script type="text/javascript" src="http://subdomain.mydomain.tld" crossorigin="*.mydomain.tld" />

2) sửa đổi apache httpd.conf bằng cách thêm phần sau vào mỗi vhost (bạn phải có thể sửa đổi mod_headers):

<IfModule mod_headers.c>
Header add Access-Control-Allow-Origin "*.mydomain.tld"
</IfModule>

Hi vọng điêu nay co ich ...

BIÊN TẬP

Trên một trong các máy chủ của tôi, tôi không thể thực hiện chức năng này ngoại trừ bằng cách thay thế

*.mydomain.tld

bởi

*

Hãy nhận biết các lỗ hổng với khả năng cho phép * lừa đảo thông tin mở rộng. Tài liệu về CORS, cùng nguồn gốc, img & phông chữ, cdn có sẵn nhưng rất ít về chi tiết crossorigin thẻ script có sẵn.


1
"* .mydomain.tld" không phải là một giá trị hợp lệ cho thuộc tính crossorigin developer.mozilla.org/en-US/docs/Web/HTML/...
icenac

1

Trong Chrome, tôi cũng nhận được "Lỗi tập lệnh" (trên dòng 0) khi tải cả HTML và Javascript từ file://. Điều này không xảy ra trong Firefox. Có lẽ bảo vệ quá mức cùng nguồn gốc của Chrome.

Tất cả đều tốt khi tải cùng một HTML và Javascript qua HTTP.


1

Làm thế nào về dưới đây. Lỗi tập lệnh không có sẵn thông qua JavaScript, vì vậy chỉ cần cách ly trường hợp cụ thể đó và xử lý nó tốt nhất có thể.

window.onerror = function (msg, url, lineNo, columnNo, error) {
    var string = msg.toLowerCase();
    var substring = "script error";
    if (string.indexOf(substring) > -1){
        alert('Script Error: See Browser Console for Detail');
    } else {
        alert(msg, url, lineNo, columnNo, error);
    }
  return false;
};

Làm thế nào để bạn đăng nhập này vào nghiệp?
CommonSenseCode

Bạn đang nói rằng bảng điều khiển trình duyệt có các chi tiết, nhưng onerror thì không?
Michael Freidgeim


0

Cả Chrome và Firefox trên iOS đều dựa trên Safari Webview nhưng chèn một loạt các tập lệnh tùy chỉnh vào mỗi trang được tải. Nếu trong bất kỳ kịch bản nào xảy ra lỗi, nó cũng được báo cáo Script error on line 0. (Trình duyệt chèn tập lệnh cũng được tính là nguồn gốc chéo)

Như tôi đã theo dõi và ghi lại trong luồng SO khác này, cả Chrome và Firefox trên iOS đều có vấn đề trong các tập lệnh tùy chỉnh của chúng xử lý các phần tử SVG một cách chính xác. Vì vậy, ngoài tất cả các câu trả lời khác trong chuỗi này: Nếu bạn sử dụng các yếu tố và <a>thẻ SVG bên trong <svg>các thẻ trên trang của mình, điều đó sẽ dẫn đến Script errorsviệc được báo cáo trong iOS Chrome và iOS Firefox.


-1

Tôi sẽ cho bạn biết cái gì đã sửa nó cho tôi trên Safari (WebKit): Nếu tôi đặt thói quen gọi lại JS thực sự trên trang , thì tôi sẽ nhận được thông tin đầy đủ. Nếu tôi đưa nó vào tệp .js qua thẻ, tôi sẽ gặp lỗi "Lỗi tập lệnh" (không có số vải lanh, v.v.).

Có lẽ điều này có liên quan đến những gì Broofa nói.

Anwyay, vì vậy bây giờ tôi có một cuộc gọi lại nhỏ trong trang, và sau đó phần còn lại của tệp bên ngoài trang.


-2

Tôi đã thực hiện một chút tìm kiếm và có vẻ như "Lỗi tập lệnh" có nghĩa là nó đã gặp sự cố khi tải một tệp mà nó được yêu cầu tìm kiếm. Đây có thể là sự cố bộ đệm ở phía máy khách hoặc có thể là sự cố máy chủ do quá tải.

Rất có thể nguyên nhân gây ra bởi một cái gì đó như thế này trong đó chính tập lệnh là tệp mà nó không thể tải, do đó xảy ra lỗi trên dòng 0.

<script type="text/javascript" src="somescript.js"></script>

Suy nghĩ tốt, nhưng chúng tôi rõ ràng bỏ qua khi một kịch bản không tải. Chúng tôi đã phát hiện lỗi đó một cách cụ thể và bỏ qua nó.
Mike Sherov

1
Làm thế nào bạn phát hiện ra khi một kịch bản không tải? Tôi nhớ có vấn đề với điều đó tại một thời điểm. script.onerrorđã không bị sa thải vì các tập lệnh bị thiếu trong một số trình duyệt.
Charlie Kilian

"Lỗi nguồn." (little-e) xuất hiện trong cả hai nguồn webkit và FF. Xem câu trả lời của tôi ở trên. fwiw.
broalid

-3

Tôi đã có kinh nghiệm

Kịch bản lỗi. dòng 0

lỗi trong một thời gian được báo cáo lại cho máy chủ của chúng tôi khi xảy ra lỗi trong trình duyệt của khách hàng. Hôm qua lần đầu tiên (sau khi giới thiệu "use strict";trong javascript của chúng tôi) tôi đã có thể sao chép vấn đề này trong Safari và Chrome trên Windows 7. Sau khi xả mã của chúng tôi bằng các câu lệnh alert (), tôi đã tìm ra lỗi này khi sử dụng biến không xác định! ví dụ: xx = 123;trong đó xx không được định nghĩa bằng một varcâu lệnh.

Safari đã báo cáo điều này như

ReferenceError: Chế độ nghiêm ngặt cấm tạo tài sản toàn cầu 'xx'

trong Web Inspector, nhưng chức năng window.onerror đã phát hiện

Kịch bản lỗi. dòng 0


-11

Cắt mã nguồn của Firefox cho thấy rằng không có "Script Error.". Vì vậy, rất có thể một số tập lệnh trên trang web của bạn đang gặp phải một lỗi chưa được xử lý như thế này:

throw new Error('Script Error.');

Có lẽ tuyên bố này chỉ đạt được trong Firefox và Chrome.

Không chắc chắn tại sao không có số dòng mặc dù. Có lẽ một số eval()vấn đề?


1
Tôi đã thử ném nó chính xác như bạn đã đề nghị. Nó không báo cáo "Lỗi Script.". Nó báo cáo "Ngoại lệ ném không bị bắt: Lỗi tập lệnh.". Mặc dù suy nghĩ tốt.
Mike Sherov

Nó cũng có thể là một trong những tiện ích mở rộng được cài đặt bởi người dùng gây ra lỗi.
Charlie Kilian

1
Không đời nào. Bạn sẽ thấy "Lỗi tập lệnh" trên tất cả các trang web nếu bạn nhìn vào các ô bên phải.
Amalgovinus

2
À, không. Đó thực sự là "Lỗi script." với một chữ "e" nhỏ. Đó là lý do tại sao tôi không tìm thấy nó trong mã nguồn.
dùng123444555621
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.