Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
ǰ¶ËÐÔÄÜÓëÒì³£Éϱ¨
 
  2613  次浏览      27
  2018-8-31
 
±à¼­ÍƼö:
±¾ÎÄÀ´×ÔÍøÂ磬±¾ÎÄÖ÷Òª½²ÊöÁËÔÚǰ¶Ë¿ª·¢ÖÐÒì³£²¶»ñµÄ·½·¨ÒÔ¼°ÐÔÄܲâÊÔ£¬Í¬Ê±½²½âÁËÈçºÎ½«ÕâЩÒì³£ºÍÐÔÄÜÊý¾ÝÈçºÎÉϱ¨¡£

¸ÅÊö

¶ÔÓÚºǫ́¿ª·¢À´Ëµ£¬¼Ç¼ÈÕÖ¾ÊÇÒ»Öַdz£³£¼ûµÄ¿ª·¢Ï°¹ß£¬Í¨³£ÎÒÃÇ»áʹÓà try...catch´úÂë¿éÀ´Ö÷¶¯²¶»ñ´íÎó¡¢¶ÔÓÚÿ´Î½Ó¿Úµ÷Óã¬Ò²»á¼Ç¼ÏÂÿ´Î½Ó¿Úµ÷ÓõÄʱ¼äÏûºÄ£¬ÒÔ±ãÎÒÃÇ¼à¿Ø·þÎñÆ÷½Ó¿ÚÐÔÄÜ£¬½øÐÐÎÊÌâÅŲ顣

¸Õ½ø¹«Ë¾Ê±£¬ÔÚ½øÐÐ Node.jsµÄ½Ó¿Ú¿ª·¢Ê±£¬ÎÒ²»Ì«Ï°¹ßÿ´ÎÅŲéÎÊÌⶼҪͨ¹ýÌø°å»úµÇÉÏ·þÎñÆ÷¿´ÈÕÖ¾£¬ºóÀ´ÂýÂýϰ¹ßÁËÕâÖÖ·½Ê½¡£

¾Ù¸öÀý×Ó£º

/**
* »ñÈ¡ÁбíÊý¾Ý
* @parma req, res
*/
exports.getList = async function (req, res) {
//»ñÈ¡ÇëÇó²ÎÊý
const openId = req.session.userinfo.openId;
logger.info(`handler getList, user openId is ${openId}`);

try {
// Äõ½ÁбíÊý¾Ý
const startTime = new Date().getTime();
let res = await ListService.getListFromDB(openId);
logger.info(`handler getList, ListService.getListFromDB cost time ${new Date().getTime() - startDate}`);
// ¶ÔÊý¾Ý´¦Àí£¬·µ»Ø¸øÇ°¶Ë
// ...
} catch(error) {
logger.error(`handler getList is error, ${JSON.stringify(error)}`);
}
};

ÒÔÏ´úÂë¾­³£»á³öÏÖÔÚÓà Node.jsµÄ½Ó¿ÚÖУ¬ÔÚ½Ó¿ÚÖлáͳ¼Æ²éѯ DBËùºÄʱ¼ä¡¢Òà»òÊÇͳ¼Æ RPC·þÎñµ÷ÓÃËùºÄʱ¼ä£¬ÒÔ±ã¼à²âÐÔÄÜÆ¿¾±£¬¶ÔÐÔÄÜ×öÓÅ»¯£»ÓÖ»òÊǶÔÒ쳣ʹÓà try ... catchÖ÷¶¯²¶»ñ£¬ÒÔ±ãËæÊ±¶ÔÎÊÌâ½øÐлØËÝ¡¢»¹Ô­ÎÊÌâµÄ³¡¾°£¬½øÐÐ bugµÄÐÞ¸´¡£

¶ø¶ÔÓÚǰ¶ËÀ´ËµÄØ£¿¿ÉÒÔ¿´ÒÔϵij¡¾°¡£

×î½üÔÚ½øÐÐÒ»¸öÐèÇ󿪷¢Ê±£¬Å¼¶û·¢ÏÖ webgläÖȾӰÏñʧ°ÜµÄÇé¿ö£¬»òÕß˵ӰÏñ»á³öÏÖ½âÎöʧ°ÜµÄÇé¿ö£¬ÎÒÃÇ¿ÉÄܸù±¾²»ÖªµÀÄÄÕÅÓ°Ïñ»á½âÎö»òäÖȾʧ°Ü£»ÓÖ»òÈç×î½ü¿ª·¢µÄÁíÍâÒ»¸öÐèÇó£¬ÎÒÃÇ»á×öÒ»¸ö¹ØÓÚ webgläÖȾʱ¼äµÄÓÅ»¯ºÍÓ°ÏñÔ¤¼ÓÔØµÄÐèÇó£¬Èç¹ûȱ·¦ÐÔÄÜ¼à¿Ø£¬¸ÃÈçºÎͳ¼ÆËù×öµÄäÖȾÓÅ»¯ºÍÓ°ÏñÔ¤¼ÓÔØÓÅ»¯µÄÓÅ»¯±ÈÀý£¬ÈçºÎÖ¤Ã÷×Ô¼ºËù×öµÄÊÂÇé¾ßÓмÛֵĨ£¿¿ÉÄÜÊÇͨ¹ý²âÊÔͬѧµÄºÚºÐ²âÊÔ£¬¶ÔÓÅ»¯Ç°ºóµÄʱ¼ä½øÐмÆÁ£¬·ÖÎö´Ó½øÈëÒ³Ãæµ½Ó°ÏñäÖȾÍê³Éµ½µ×¾­¹ýÁ˶àÉÙ֡ͼÏñ¡£ÕâÑùµÄÊý¾Ý£¬¿ÉÄܼȲ»×¼È·¡¢ÓÖ½ÏÎªÆ¬Ãæ£¬ÉèÏë²âÊÔͬѧ²¢²»ÊÇÕæÕýµÄÓû§£¬Ò²ÎÞ·¨»¹Ô­ÕæÊµµÄÓû§ËûÃÇËù´¦µÄÍøÂç»·¾³¡£»Ø¹ýÍ·À´·¢ÏÖ£¬ÎÒÃǵÄÏîÄ¿£¬ËäÈ»ÔÚ·þÎñ¶Ë²ãÃæ×öºÃÁËÈÕÖ¾ºÍÐÔÄÜͳ¼Æ£¬µ«ÔÚǰ¶Ë¶ÔÒì³£µÄ¼à¿ØºÍÐÔÄܵÄͳ¼Æ¡£¶ÔÓÚǰ¶ËµÄÐÔÄÜÓëÒì³£Éϱ¨µÄ¿ÉÐÐÐÔ̽Ë÷ÊÇÓбØÒªµÄ¡£

Òì³£²¶»ñ

¶ÔÓÚǰ¶ËÀ´Ëµ£¬ÎÒÃÇÐèÒªµÄÒì³£²¶»ñÎÞ·ÇΪÒÔÏÂÁ½ÖÖ£º

½Ó¿Úµ÷ÓÃÇé¿ö£»

Ò³ÃæÂß¼­ÊÇ·ñ´íÎó£¬ÀýÈ磬Óû§½øÈëÒ³ÃæºóÒ³ÃæÏÔʾ°×ÆÁ£»

¶ÔÓÚ½Ó¿Úµ÷ÓÃÇé¿ö£¬ÔÚǰ¶Ëͨ³£ÐèÒªÉϱ¨¿Í»§¶ËÏà¹Ø²ÎÊý£¬ÀýÈ磺Óû§OSÓëä¯ÀÀÆ÷°æ±¾¡¢ÇëÇó²ÎÊý£¨ÈçÒ³ÃæID£©£»¶ø¶ÔÓÚÒ³ÃæÂß¼­ÊÇ·ñ´íÎóÎÊÌ⣬ͨ³£³ýÁËÓû§OSÓëä¯ÀÀÆ÷°æ±¾Í⣬ÐèÒªµÄÊDZ¨´íµÄ¶ÑÕ»ÐÅÏ¢¼°¾ßÌ屨´íλÖá£

Òì³£²¶»ñ·½·¨

È«¾Ö²¶»ñ

¿ÉÒÔͨ¹ýÈ«¾Ö¼àÌýÒì³£À´²¶»ñ£¬Í¨¹ý window.onerror»òÕß addEventListener£¬¿´ÒÔÏÂÀý×Ó£º

window.onerror = function(errorMessage, scriptURI, lineNo, columnNo, error) {
console.log('errorMessage: ' + errorMessage); // Òì³£ÐÅÏ¢
console.log('scriptURI: ' + scriptURI); // Òì³£Îļþ·¾¶
console.log('lineNo: ' + lineNo); // Òì³£ÐкÅ
console.log('columnNo: ' + columnNo); // Òì³£ÁкÅ
console.log('error: ' + error); // Òì³£¶ÑÕ»ÐÅÏ¢
// ...
// Òì³£Éϱ¨
};
throw new Error('ÕâÊÇÒ»¸ö´íÎó');

ͨ¹ý window.onerrorʼþ£¬¿ÉÒԵõ½¾ßÌåµÄÒì³£ÐÅÏ¢¡¢Òì³£ÎļþµÄURL¡¢Òì³£µÄÐкÅÓëÁкż°Òì³£µÄ¶ÑÕ»ÐÅÏ¢£¬ÔÙ²¶»ñÒì³£ºó£¬Í³Ò»Éϱ¨ÖÁÎÒÃǵÄÈÕÖ¾·þÎñÆ÷¡£

Òà»òÊÇ£¬Í¨¹ý window.addEventListener·½·¨À´½øÐÐÒì³£Éϱ¨£¬µÀÀíͬÀí£º

window.addEventListener('error', function() {
console.log(error);
// ...
// Òì³£Éϱ¨
});
throw new Error('ÕâÊÇÒ»¸ö´íÎó');

try... catch

ʹÓà try... catchËäÈ»Äܹ»½ÏºÃµØ½øÐÐÒì³£²¶»ñ£¬²»ÖÁÓÚʹµÃÒ³ÃæÓÉÓÚÒ»´¦´íÎó¹Òµô£¬µ« try ... catch²¶»ñ·½Ê½ÏԵùýÓÚÓ·Ö×£¬´ó¶à´úÂëʹÓà try ...catch°ü¹ü£¬Ó°Ïì´úÂë¿É¶ÁÐÔ¡£

³£¼ûÎÊÌâ

¿çÓò½Å±¾ÎÞ·¨×¼È·²¶»ñÒì³£

ͨ³£Çé¿öÏ£¬ÎÒÃÇ»á°Ñ¾²Ì¬×ÊÔ´£¬Èç JavaScript½Å±¾·Åµ½×¨Ãŵľ²Ì¬×ÊÔ´·þÎñÆ÷£¬Òà»òÕß CDN£¬¿´ÒÔÏÂÀý×Ó£º

<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<script type="text/javascript">
// ÔÚindex.html
window.onerror = function(errorMessage, scriptURI, lineNo, columnNo, error) {
console.log('errorMessage: ' + errorMessage); // Òì³£ÐÅÏ¢
console.log('scriptURI: ' + scriptURI); // Òì³£Îļþ·¾¶
console.log('lineNo: ' + lineNo); // Òì³£ÐкÅ
console.log('columnNo: ' + columnNo); // Òì³£ÁкÅ
console.log('error: ' + error); // Òì³£¶ÑÕ»ÐÅÏ¢
// ...
// Òì³£Éϱ¨
};

</script>
<script src="./error.js"></script>
</body>
</html>

// error.js
throw new Error('ÕâÊÇÒ»¸ö´íÎó');

½á¹ûÏÔʾ£¬¿çÓòÖ®ºó window.onerror¸ù±¾²¶»ñ²»µ½ÕýÈ·µÄÒì³£ÐÅÏ¢£¬¶øÊÇͳһ·µ»ØÒ»¸ö Script error£¬

½â¾ö·½°¸£º¶Ô script±êÇ©Ôö¼ÓÒ»¸ö crossorigin=¡±anonymous¡±£¬²¢ÇÒ·þÎñÆ÷Ìí¼Ó Access-Control-Allow-Origin¡£

<script src="http://cdn.xxx.com/index.js" crossorigin="anonymous"></script>

sourceMap

ͨ³£ÔÚÉú²ú»·¾³ÏµĴúÂëÊǾ­¹ý webpack´ò°üºóѹËõ»ìÏýµÄ´úÂ룬ËùÒÔÎÒÃÇ¿ÉÄÜ»áÓöµ½ÕâÑùµÄÎÊÌ⣬ÈçͼËùʾ£º

ÎÒÃÇ·¢ÏÖËùÓеı¨´íµÄ´úÂëÐÐÊý¶¼ÔÚµÚÒ»ÐÐÁË£¬ÎªÊ²Ã´ÄØ£¿ÕâÊÇÒòΪÔÚÉú²ú»·¾³Ï£¬ÎÒÃǵĴúÂ뱻ѹËõ³ÉÁËÒ»ÐУº

!function(e){var n={};function r(o){if(n[o])return
n[o].exports;var t=n[o]={i:o,l:!1,exports:{}};return
e[o].call(t.exports,t,t.exports,r),t.l=!0,t.exports}
r.m=e,r.c=n,r.d=function(e,n,o){r.o(e,n)||
Object.defineProperty(e,n,{enumerable:!0,get:o})},
r.r=function(e){"undefined"!=typeof Symbol&&
Symbol.toStringTag&&Object.defineProperty
(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty
(e,"__esModule",{value:!0})},r.t=function(e,n)
{if(1&n&&(e=r(e)),8&n)return e;if(4&n&&"object"==typeof
e&&e&&e.__esModule)return e;var o=Object.create(null);
if(r.r(o),Object.defineProperty(o,"default",
{enumerable:!0,value:e}),2&n&&"string"!=typeof
e)for(var t in e)r.d(o,t,function(n){return e[n]}.bind(null,t));
return o},r.n=function(e){var n=e&&e.__esModule?function(){return
e.default}:function(){return e};return r.d(n,"a",n),n},r.o
=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)}
,r.p="",r(r.s=0)}([function(e,n){throw
window.onerror=function(e,n,r,o,t){console.log("errorMessage:
"+e),console.log("scriptURI: "+n),console.log("lineNo:
"+r),console.log("columnNo: "+o),console.log("error:
"+t);var l={errorMessage:e||null,scriptURI:n||null,
lineNo:r||null,columnNo:o||null,stack:t&&t.stack?t.stack:null};
if(XMLHttpRequest){var u=new XMLHttpRequest;
u.open("post","/middleware/errorMsg",!0),
u.setRequestHeader("Content-Type","application/json"),
u.send(JSON.stringify(l))}},new Error("ÕâÊÇÒ»¸ö´íÎó")}]);

ÔÚÎҵĿª·¢¹ý³ÌÖÐÒ²Óöµ½¹ýÕâ¸öÎÊÌ⣬ÎÒÔÚ¿ª·¢Ò»¸ö¹¦ÄÜ×é¼þ¿âµÄʱºò£¬Ê¹Óà npm linkÁËÎÒµÄ×é¼þ¿â£¬µ«ÊÇÓÉÓÚ×é¼þ¿â±» npm linkºóÊÇ´ò°üºóµÄÉú²ú»·¾³ÏµĴúÂ룬ËùÓеı¨´í¶¼¶¨Î»µ½Á˵ÚÒ»ÐС£

½â¾ö°ì·¨ÊÇ¿ªÆô webpackµÄ source-map£¬ÎÒÃÇÀûÓà webpack´ò°üºóµÄÉú³ÉµÄÒ»·Ý .mapµÄ½Å±¾Îļþ¾Í¿ÉÒÔÈÃä¯ÀÀÆ÷¶Ô´íÎóλÖýøÐÐ×·×ÙÁË¡£´Ë´¦¿ÉÒԲο¼webpack document¡£

Æäʵ¾ÍÊÇ webpack.config.jsÖмÓÉÏÒ»ÐÐ devtool: 'source-map'£¬ÈçÏÂËùʾ£¬ÎªÊ¾ÀýµÄ webpack.config.js£º

var path = require('path');
module.exports = {
devtool: 'source-map',
mode: 'development',
entry: './client/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'client')
}
}

ÔÚ webpack´ò°üºóÉú³É¶ÔÓ¦µÄ source-map£¬ÕâÑùä¯ÀÀÆ÷¾ÍÄܹ»¶¨Î»µ½¾ßÌå´íÎóµÄλÖãº

¿ªÆô source-mapµÄȱÏÝÊǼæÈÝÐÔ£¬Ä¿Ç°Ö»ÓÐ Chromeä¯ÀÀÆ÷ºÍ Firefoxä¯ÀÀÆ÷²Å¶Ô source-mapÖ§³Ö¡£²»¹ýÎÒÃǶÔÕâÒ»ÀàÇé¿öÒ²Óнâ¾ö°ì·¨¡£¿ÉÒÔʹÓÃÒýÈë npm¿âÀ´Ö§³Ö source-map£¬¿ÉÒԲο¼mozilla/source-map¡£Õâ¸ö npm¿â¼È¿ÉÒÔÔËÐÐÔÚ¿Í»§¶ËÒ²¿ÉÒÔÔËÐÐÔÚ·þÎñ¶Ë£¬²»¹ý¸üÎªÍÆ¼öµÄÊÇÔÚ·þÎñ¶ËʹÓà Node.js¶Ô½ÓÊÕµ½µÄÈÕÖ¾ÐÅϢʱʹÓà source-map½âÎö£¬ÒÔ±ÜÃâÔ´´úÂëµÄй¶Ôì³É·çÏÕ£¬ÈçÏ´úÂëËùʾ£º

const express = require('express');
const fs = require('fs');
const router = express.Router();
const sourceMap = require('source-map');
const path = require('path');
const resolve = file => path.resolve(__dirname, file);
// ¶¨Òåpost½Ó¿Ú
router.get('/error/', async function(req, res) {
// »ñȡǰ¶Ë´«¹ýÀ´µÄ±¨´í¶ÔÏó
let error = JSON.parse(req.query.error);
let url = error.scriptURI; // ѹËõÎļþ·¾¶
if (url) {
let fileUrl = url.slice(url.indexOf('client/')) + '.map'; // mapÎļþ·¾¶
// ½âÎösourceMap
let consumer = await new sourceMap.SourceMapConsumer(fs.readFileSync(resolve('../' + fileUrl), 'utf8')); // ·µ»ØÒ»¸öpromise¶ÔÏó
// ½âÎöԭʼ±¨´íÊý¾Ý
let result = consumer.originalPositionFor({
line: error.lineNo, // ѹËõºóµÄÐкÅ
column: error.columnNo // ѹËõºóµÄÁкÅ
});
console.log(result);
}
});
module.exports = router;

ÈçÏÂͼËùʾ£¬ÎÒÃÇÒѾ­¿ÉÒÔ¿´µ½£¬ÔÚ·þÎñ¶ËÒѾ­³É¹¦½âÎö³öÁ˾ßÌå´íÎóµÄÐкš¢Áкţ¬ÎÒÃÇ¿ÉÒÔͨ¹ýÈÕÖ¾µÄ·½Ê½½øÐмǼ£¬´ïµ½ÁËǰ¶ËÒì³£¼à¿ØµÄÄ¿µÄ¡£

Vue²¶»ñÒì³£

ÔÚÎÒµÄÏîÄ¿ÖоÍÓöµ½ÕâÑùµÄÎÊÌ⣬ʹÓÃÁË js-trackerÕâÑùµÄ²å¼þÀ´Í³Ò»½øÐÐÈ«¾ÖµÄÒì³£²¶»ñºÍÈÕÖ¾Éϱ¨£¬½á¹û·¢ÏÖÎÒÃǸù±¾²¶»ñ²»µ½ Vue×é¼þµÄÒì³££¬²éÔÄ×ÊÁϵÃÖª£¬ÔÚ VueÖУ¬Òì³£¿ÉÄܱ» Vue×ÔÉí¸ø try ... catchÁË£¬²»»á´«µ½ window.onerrorʼþ´¥·¢£¬ÄÇôÎÒÃÇÈçºÎ°Ñ Vue×é¼þÖеÄÒì³£×÷ͳһ²¶»ñÄØ£¿

ʹÓÃVue.config.errorHandlerÕâÑùµÄ VueÈ«¾ÖÅäÖ㬿ÉÒÔÔÚ VueÖ¸¶¨×é¼þµÄäÖȾºÍ¹Û²ìÆÚ¼äδ²¶»ñ´íÎóµÄ´¦Àíº¯Êý¡£Õâ¸ö´¦Àíº¯Êý±»µ÷ÓÃʱ£¬¿É»ñÈ¡´íÎóÐÅÏ¢ºÍ Vue ʵÀý¡£

Vue.config.errorHandler = function (err, vm, info) {
// handle error
// `info` ÊÇ Vue ÌØ¶¨µÄ´íÎóÐÅÏ¢£¬±ÈÈç´íÎóËùÔÚµÄÉúÃüÖÜÆÚ¹³×Ó
// Ö»ÔÚ 2.2.0+ ¿ÉÓÃ
}

ÔÚ ReactÖУ¬¿ÉÒÔʹÓà ErrorBoundary×é¼þ°üÀ¨ÒµÎñ×é¼þµÄ·½Ê½½øÐÐÒì³£²¶»ñ£¬ÅäºÏ React 16.0+гöµÄ componentDidCatch API£¬¿ÉÒÔʵÏÖͳһµÄÒì³£²¶»ñºÍÈÕÖ¾Éϱ¨¡£

class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}

componentDidCatch(error, info) {
// Display fallback UI
this.setState({ hasError: true });
// You can also log the error to an error reporting service
logErrorToMyService(error, info);
}

render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}

ʹÓ÷½Ê½ÈçÏ£º

<ErrorBoundary>
<MyWidget />
</ErrorBoundary>

ÐÔÄÜ¼à¿Ø

×î¼òµ¥µÄÐÔÄÜ¼à¿Ø

×î³£¼ûµÄÐÔÄÜ¼à¿ØÐèÇóÔòÊÇÐèÒªÎÒÃÇͳ¼ÆÓû§´Ó¿ªÊ¼ÇëÇóÒ³Ãæµ½ËùÓÐ DOMÔªËØäÖȾÍê³ÉµÄʱ¼ä£¬Ò²¾ÍÊÇË׳ƵÄÊׯÁ¼ÓÔØÊ±¼ä£¬ DOMÌṩÁËÕâÒ»½Ó¿Ú£¬¼àÌý documentµÄ DOMContentLoadedʼþÓë windowµÄ loadʼþ¿Éͳ¼ÆÒ³ÃæÊׯÁ¼ÓÔØÊ±¼ä¼´ËùÓÐ DOMäÖȾʱ¼ä£º

<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript">
// ¼ÇÂ¼Ò³Ãæ¼ÓÔØ¿ªÊ¼Ê±¼ä
var timerStart = Date.now();
</script>
<!-- ¼ÓÔØ¾²Ì¬×ÊÔ´£¬ÈçÑùʽ×ÊÔ´ -->
</head>
<body>
<!-- ¼ÓÔØ¾²Ì¬JS×ÊÔ´ -->
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function() {
console.log("DOM ¹ÒÔØÊ±¼ä: ", Date.now() - timerStart);
// ÐÔÄÜÈÕÖ¾Éϱ¨
});
window.addEventListener('load', function() {
console.log("ËùÓÐ×ÊÔ´¼ÓÔØÍê³Éʱ¼ä: ", Date.now()-timerStart);
// ÐÔÄÜÈÕÖ¾Éϱ¨
});
</script>
</body>
</html>

¶ÔÓÚʹÓÿò¼Ü£¬Èç Vue»òÕß˵ React£¬×é¼þÊÇÒì²½äÖȾȻºó¹ÒÔØµ½ DOMµÄ£¬ÔÚÒ³Ãæ³õʼ»¯Ê±²¢Ã»ÓÐÌ«¶àµÄ DOM½Úµã£¬¿ÉÒԲο¼ÏÂÎĹØÓÚÊׯÁʱ¼ä²É¼¯×Ô¶¯»¯µÄ½â¾ö·½°¸À´¶ÔäÖȾʱ¼ä½øÐдòµã¡£

performance

µ«ÊÇÒÔÉÏʱ¼äµÄ¼à¿Ø¹ýÓÚ´ÖÂÔ£¬ÀýÈçÎÒÃÇÏëͳ¼ÆÎĵµµÄÍøÂç¼ÓÔØºÄʱ¡¢½âÎö DOMµÄºÄʱÓëäÖȾ DOMµÄºÄʱ£¬¾Í²»Ì«ºÃ°ìµ½ÁË£¬ËùÐÒµÄÊÇä¯ÀÀÆ÷ÌṩÁË window.performance½Ó¿Ú£¬¾ßÌå¿É¼ûMDNÎĵµ

¼¸ºõËùÓÐä¯ÀÀÆ÷¶¼Ö§³Ö window.performance½Ó¿Ú£¬ÏÂÃæÀ´¿´¿´ÔÚ¿ØÖÆÌ¨´òÓ¡ window.performance¿ÉÒԵõ½Ð©Ê²Ã´£º

¿ÉÒÔ¿´µ½£¬ window,performanceÖ÷Òª°üÀ¨ÓÐ memory¡¢ navigation¡¢ timingÒÔ¼° timeOrigin¼° onresourcetimingbufferfull·½·¨¡£

navigation¶ÔÏóÌṩÁËÔÚÖ¸¶¨µÄʱ¼ä¶ÎÀï·¢ÉúµÄ²Ù×÷Ïà¹ØÐÅÏ¢£¬°üÀ¨Ò³ÃæÊǼÓÔØ»¹ÊÇˢС¢·¢ÉúÁ˶àÉÙ´ÎÖØ¶¨ÏòµÈµÈ¡£

timing¶ÔÏó°üº¬ÑÓ³ÙÏà¹ØµÄÐÔÄÜÐÅÏ¢¡£ÕâÊÇÎÒÃÇÒ³Ãæ¼ÓÔØÐÔÄÜÓÅ»¯ÐèÇóÖÐÖ÷ÒªÉϱ¨µÄÏà¹ØÐÅÏ¢¡£

memoryΪ ChromeÌí¼ÓµÄÒ»¸ö·Ç±ê×¼À©Õ¹£¬Õâ¸öÊôÐÔÌṩÁËÒ»¸ö¿ÉÒÔ»ñÈ¡µ½»ù±¾ÄÚ´æÊ¹ÓÃÇé¿öµÄ¶ÔÏó¡£ÔÚÆäËüä¯ÀÀÆ÷Ó¦¸Ã¿¼Âǵ½Õâ¸ö APIµÄ¼æÈÝ´¦Àí¡£

timeOriginÔò·µ»ØÐÔÄܲâÁ¿¿ªÊ¼Ê±µÄʱ¼äµÄ¸ß¾«¶Èʱ¼ä´Á¡£ÈçͼËùʾ£¬¾«È·µ½ÁËСÊýµãºóËÄλ¡£

onresourcetimingbufferfull·½·¨£¬ËüÊÇÒ»¸öÔÚ resourcetimingbufferfullʼþ´¥·¢Ê±»á±»µ÷ÓÃµÄ event handler¡£Õâ¸öʼþµ±ä¯ÀÀÆ÷µÄ×ÊԴʱ¼äÐÔÄÜ»º³åÇøÒÑÂúʱ»á´¥·¢¡£¿ÉÒÔͨ¹ý¼àÌýÕâһʼþ´¥·¢À´Ô¤¹ÀÒ³Ãæ crash£¬Í³¼ÆÒ³Ãæ crash¸ÅÂÊ£¬ÒÔ±ãºóÆÚµÄÐÔÄÜÓÅ»¯£¬ÈçÏÂʾÀýËùʾ£º

function buffer_full(event) {
console.log("WARNING: Resource Timing Buffer is FULL!");
performance.setResourceTimingBufferSize(200);
}
function init() {
// Set a callback if the resource buffer becomes filled
performance.onresourcetimingbufferfull = buffer_full;
}
<body onload="init()">

¼ÆËãÍøÕ¾ÐÔÄÜ

ʹÓà performanceµÄ timingÊôÐÔ£¬¿ÉÒÔÄõ½Ò³ÃæÐÔÄÜÏà¹ØµÄÊý¾Ý£¬ÕâÀïÔںܶàÎÄÕ¶¼ÓÐÌáµ½¹ØÓÚÀûÓà window.performance.timing¼ÇÂ¼Ò³ÃæÐÔÄܵÄÎÄÕ£¬ÀýÈç alloyteamÍŶÓдµÄ³õ̽ performance ¨C ¼à¿ØÍøÒ³Óë³ÌÐòÐÔÄÜ£¬¶ÔÓÚ timingµÄ¸÷ÏîÊôÐÔº¬Ò壬¿ÉÒÔ½èÖúÕª×Ô´ËÎĵÄÏÂͼÀí½â£¬ÒÔÏ´úÂëÕª×Ô´ËÎÄ×÷Ϊ¼ÆËãÍøÕ¾ÐÔÄܵŤ¾ßº¯Êý²Î¿¼£º

// »ñÈ¡ performance Êý¾Ý
var performance = {
// memory ÊǷDZê×¼ÊôÐÔ£¬Ö»ÔÚ Chrome ÓÐ
// ²Æ¸»ÎÊÌ⣺ÎÒÓжàÉÙÄÚ´æ
memory: {
usedJSHeapSize: 16100000, // JS ¶ÔÏ󣨰üÀ¨V8ÒýÇæÄÚ²¿¶ÔÏó£©Õ¼ÓõÄÄڴ棬һ¶¨Ð¡ÓÚ totalJSHeapSize
totalJSHeapSize: 35100000, // ¿ÉʹÓõÄÄÚ´æ
jsHeapSizeLimit: 793000000 // ÄÚ´æ´óСÏÞÖÆ
},
// ÕÜѧÎÊÌ⣺ÎÒ´ÓÄÄÀïÀ´£¿
navigation: {
redirectCount: 0, // Èç¹ûÓÐÖØ¶¨ÏòµÄ»°£¬Ò³ÃæÍ¨¹ý¼¸´ÎÖØ¶¨ÏòÌø×ª¶øÀ´
type: 0 // 0 ¼´ TYPE_NAVIGATENEXT Õý³£½øÈëµÄÒ³Ãæ£¨·ÇˢС¢·ÇÖØ¶¨ÏòµÈ£©
// 1 ¼´ TYPE_RELOAD ͨ¹ý window.location.reload() ˢеÄÒ³Ãæ
// 2 ¼´ TYPE_BACK_FORWARD ͨ¹ýä¯ÀÀÆ÷µÄǰ½øºóÍ˰´Å¥½øÈëµÄÒ³Ãæ£¨ÀúÊ·¼Ç¼£©
// 255 ¼´ TYPE_UNDEFINED ·ÇÒÔÉÏ·½Ê½½øÈëµÄÒ³Ãæ
},

timing: {
// ÔÚͬһ¸öä¯ÀÀÆ÷ÉÏÏÂÎÄÖУ¬Ç°Ò»¸öÍøÒ³£¨Óëµ±Ç°Ò³Ãæ²»Ò»¶¨Í¬Óò£©unload µÄʱ¼ä´Á£¬Èç¹ûÎÞǰһ¸öÍøÒ³ unload £¬ÔòÓë fetchStart ÖµÏàµÈ
navigationStart: 1441112691935,

// ǰһ¸öÍøÒ³£¨Óëµ±Ç°Ò³ÃæÍ¬Óò£©unload µÄʱ¼ä´Á£¬Èç¹ûÎÞǰһ¸öÍøÒ³ unload »òÕßǰһ¸öÍøÒ³Óëµ±Ç°Ò³Ãæ²»Í¬Óò£¬ÔòֵΪ 0
unloadEventStart: 0,

// ºÍ unloadEventStart Ïà¶ÔÓ¦£¬·µ»ØÇ°Ò»¸öÍøÒ³ unload ʼþ°ó¶¨µÄ»Øµ÷º¯ÊýÖ´ÐÐÍê±ÏµÄʱ¼ä´Á
unloadEventEnd: 0,

// µÚÒ»¸ö HTTP ÖØ¶¨Ïò·¢ÉúʱµÄʱ¼ä¡£ÓÐÌø×ªÇÒÊÇͬÓòÃûÄÚµÄÖØ¶¨Ïò²ÅË㣬·ñÔòֵΪ 0
redirectStart: 0,

// ×îºóÒ»¸ö HTTP ÖØ¶¨ÏòÍê³ÉʱµÄʱ¼ä¡£ÓÐÌø×ªÇÒÊÇͬÓòÃûÄÚ²¿µÄÖØ¶¨Ïò²ÅË㣬·ñÔòֵΪ 0
redirectEnd: 0,

// ä¯ÀÀÆ÷×¼±¸ºÃʹÓà HTTP ÇëÇóץȡÎĵµµÄʱ¼ä£¬Õâ·¢ÉúÔÚ¼ì²é±¾µØ»º´æÖ®Ç°
fetchStart: 1441112692155,

// DNS ÓòÃû²éѯ¿ªÊ¼µÄʱ¼ä£¬Èç¹ûʹÓÃÁ˱¾µØ»º´æ£¨¼´ÎÞ DNS ²éѯ£©»ò³Ö¾ÃÁ¬½Ó£¬ÔòÓë fetchStart ÖµÏàµÈ
domainLookupStart: 1441112692155,

// DNS ÓòÃû²éѯÍê³ÉµÄʱ¼ä£¬Èç¹ûʹÓÃÁ˱¾µØ»º´æ£¨¼´ÎÞ DNS ²éѯ£©»ò³Ö¾ÃÁ¬½Ó£¬ÔòÓë fetchStart ÖµÏàµÈ
domainLookupEnd: 1441112692155,

// HTTP£¨TCP£© ¿ªÊ¼½¨Á¢Á¬½ÓµÄʱ¼ä£¬Èç¹ûÊdz־ÃÁ¬½Ó£¬ÔòÓë fetchStart ÖµÏàµÈ
// ×¢ÒâÈç¹ûÔÚ´«Êä²ã·¢ÉúÁË´íÎóÇÒÖØÐ½¨Á¢Á¬½Ó£¬ÔòÕâÀïÏÔʾµÄÊÇн¨Á¢µÄÁ¬½Ó¿ªÊ¼µÄʱ¼ä
connectStart: 1441112692155,

// HTTP£¨TCP£© Íê³É½¨Á¢Á¬½ÓµÄʱ¼ä£¨Íê³ÉÎÕÊÖ£©£¬Èç¹ûÊdz־ÃÁ¬½Ó£¬ÔòÓë fetchStart ÖµÏàµÈ
// ×¢ÒâÈç¹ûÔÚ´«Êä²ã·¢ÉúÁË´íÎóÇÒÖØÐ½¨Á¢Á¬½Ó£¬ÔòÕâÀïÏÔʾµÄÊÇн¨Á¢µÄÁ¬½ÓÍê³ÉµÄʱ¼ä
// ×¢ÒâÕâÀïÎÕÊÖ½áÊø£¬°üÀ¨°²È«Á¬½Ó½¨Á¢Íê³É¡¢SOCKS ÊÚȨͨ¹ý
connectEnd: 1441112692155,

// HTTPS Á¬½Ó¿ªÊ¼µÄʱ¼ä£¬Èç¹û²»Êǰ²È«Á¬½Ó£¬ÔòֵΪ 0
secureConnectionStart: 0,

// HTTP ÇëÇó¶ÁÈ¡ÕæÊµÎĵµ¿ªÊ¼µÄʱ¼ä£¨Íê³É½¨Á¢Á¬½Ó£©£¬°üÀ¨´Ó±¾µØ¶ÁÈ¡»º´æ
// Á¬½Ó´íÎóÖØÁ¬Ê±£¬ÕâÀïÏÔʾµÄÒ²ÊÇн¨Á¢Á¬½ÓµÄʱ¼ä
requestStart: 1441112692158,

// HTTP ¿ªÊ¼½ÓÊÕÏìÓ¦µÄʱ¼ä£¨»ñÈ¡µ½µÚÒ»¸ö×Ö½Ú£©£¬°üÀ¨´Ó±¾µØ¶ÁÈ¡»º´æ
responseStart: 1441112692686,

// HTTP ÏìӦȫ²¿½ÓÊÕÍê³ÉµÄʱ¼ä£¨»ñÈ¡µ½×îºóÒ»¸ö×Ö½Ú£©£¬°üÀ¨´Ó±¾µØ¶ÁÈ¡»º´æ
responseEnd: 1441112692687,

// ¿ªÊ¼½âÎöäÖȾ DOM Ê÷µÄʱ¼ä£¬´Ëʱ Document.readyState ±äΪ loading£¬²¢½«Å׳ö readystatechange Ïà¹ØÊ¼þ
domLoading: 1441112692690,

// Íê³É½âÎö DOM Ê÷µÄʱ¼ä£¬Document.readyState ±äΪ interactive£¬²¢½«Å׳ö readystatechange Ïà¹ØÊ¼þ
// ×¢ÒâÖ»ÊÇ DOM Ê÷½âÎöÍê³É£¬Õâʱºò²¢Ã»ÓпªÊ¼¼ÓÔØÍøÒ³ÄÚµÄ×ÊÔ´
domInteractive: 1441112693093,

// DOM ½âÎöÍê³Éºó£¬ÍøÒ³ÄÚ×ÊÔ´¼ÓÔØ¿ªÊ¼µÄʱ¼ä
// ÔÚ DOMContentLoaded ʼþÅ׳öǰ·¢Éú
domContentLoadedEventStart: 1441112693093,

// DOM ½âÎöÍê³Éºó£¬ÍøÒ³ÄÚ×ÊÔ´¼ÓÔØÍê³ÉµÄʱ¼ä£¨Èç JS ½Å±¾¼ÓÔØÖ´ÐÐÍê±Ï£©
domContentLoadedEventEnd: 1441112693101,

// DOM Ê÷½âÎöÍê³É£¬ÇÒ×ÊÔ´Ò²×¼±¸¾ÍÐ÷µÄʱ¼ä£¬Document.readyState ±äΪ complete£¬²¢½«Å׳ö readystatechange Ïà¹ØÊ¼þ
domComplete: 1441112693214,

// load ʼþ·¢Ë͸øÎĵµ£¬Ò²¼´ load »Øµ÷º¯Êý¿ªÊ¼Ö´ÐеÄʱ¼ä
// ×¢ÒâÈç¹ûûÓÐ°ó¶¨ load ʼþ£¬ÖµÎª 0
loadEventStart: 1441112693214,

// load ʼþµÄ»Øµ÷º¯ÊýÖ´ÐÐÍê±ÏµÄʱ¼ä
loadEventEnd: 1441112693215

// ×Öĸ˳Ðò
// connectEnd: 1441112692155,
// connectStart: 1441112692155,
// domComplete: 1441112693214,
// domContentLoadedEventEnd: 1441112693101,
// domContentLoadedEventStart: 1441112693093,
// domInteractive: 1441112693093,
// domLoading: 1441112692690,
// domainLookupEnd: 1441112692155,
// domainLookupStart: 1441112692155,
// fetchStart: 1441112692155,
// loadEventEnd: 1441112693215,
// loadEventStart: 1441112693214,
// navigationStart: 1441112691935,
// redirectEnd: 0,
// redirectStart: 0,
// requestStart: 1441112692158,
// responseEnd: 1441112692687,
// responseStart: 1441112692686,
// secureConnectionStart: 0,
// unloadEventEnd: 0,
// unloadEventStart: 0
}
};

// ¼ÆËã¼ÓÔØÊ±¼ä
function getPerformanceTiming() {
var performance = window.performance;
if (!performance) {
// µ±Ç°ä¯ÀÀÆ÷²»Ö§³Ö
console.log('ÄãµÄä¯ÀÀÆ÷²»Ö§³Ö performance ½Ó¿Ú');
return;
}
var t = performance.timing;
var times = {};
//¡¾ÖØÒª¡¿Ò³Ãæ¼ÓÔØÍê³ÉµÄʱ¼ä
//¡¾Ô­Òò¡¿Õ⼸ºõ´ú±íÁËÓû§µÈ´ýÒ³Ãæ¿ÉÓõÄʱ¼ä
times.loadPage = t.loadEventEnd - t.navigationStart;
//¡¾ÖØÒª¡¿½âÎö DOM Ê÷½á¹¹µÄʱ¼ä
//¡¾Ô­Òò¡¿·´Ê¡ÏÂÄãµÄ DOM Ê÷ǶÌ×ÊDz»ÊÇÌ«¶àÁË£¡
times.domReady = t.domComplete - t.responseEnd;
//¡¾ÖØÒª¡¿Öض¨ÏòµÄʱ¼ä
//¡¾Ô­Òò¡¿¾Ü¾øÖض¨Ïò£¡±ÈÈ磬http://example.com/ ¾Í²»¸Ãд³É http://example.com
times.redirect = t.redirectEnd - t.redirectStart;
//¡¾ÖØÒª¡¿DNS ²éѯʱ¼ä
//¡¾Ô­Òò¡¿DNS Ô¤¼ÓÔØ×öÁËô£¿Ò³ÃæÄÚÊDz»ÊÇʹÓÃÁËÌ«¶à²»Í¬µÄÓòÃûµ¼ÖÂÓòÃû²éѯµÄʱ¼äÌ«³¤£¿
// ¿ÉʹÓà HTML5 Prefetch Ô¤²éѯ DNS £¬¼û£º[HTML5 prefetch](http://segmentfault.com/a/1190000000633364)
times.lookupDomain = t.domainLookupEnd - t.domainLookupStart;
//¡¾ÖØÒª¡¿¶ÁÈ¡Ò³ÃæµÚÒ»¸ö×Ö½ÚµÄʱ¼ä
//¡¾Ô­Òò¡¿Õâ¿ÉÒÔÀí½âΪÓû§Äõ½ÄãµÄ×ÊÔ´Õ¼ÓõÄʱ¼ä£¬¼ÓÒìµØ»ú·¿ÁËô£¬¼ÓCDN ´¦ÀíÁËô£¿¼Ó´ø¿íÁËô£¿¼Ó CPU ÔËËãËÙ¶ÈÁËô£¿
// TTFB ¼´ Time To First Byte µÄÒâ˼
//¡¾ÖØÒª¡¿ÄÚÈݼÓÔØÍê³ÉµÄʱ¼ä
//¡¾Ô­Òò¡¿Ò³ÃæÄÚÈݾ­¹ý gzip ѹËõÁËô£¬¾²Ì¬×ÊÔ´ css/js µÈѹËõÁËô£¿
times.request = t.responseEnd - t.requestStart;
//¡¾ÖØÒª¡¿Ö´ÐÐ onload »Øµ÷º¯ÊýµÄʱ¼ä
//¡¾Ô­Òò¡¿ÊÇ·ñÌ«¶à²»±ØÒªµÄ²Ù×÷¶¼·Åµ½ onload »Øµ÷º¯ÊýÀïÖ´ÐÐÁË£¬¿¼ÂǹýÑÓ³Ù¼ÓÔØ¡¢°´Ðè¼ÓÔØµÄ²ßÂÔô£¿
times.loadEvent = t.loadEventEnd - t.loadEventStart;
// DNS »º´æÊ±¼ä
times.appcache = t.domainLookupStart - t.fetchStart;
// Ð¶ÔØÒ³ÃæµÄʱ¼ä
times.unloadEvent = t.unloadEventEnd - t.unloadEventStart;
// TCP ½¨Á¢Á¬½ÓÍê³ÉÎÕÊÖµÄʱ¼ä
times.connect = t.connectEnd - t.connectStart;
return times;
}

ÈÕÖ¾Éϱ¨

µ¥¶ÀµÄÈÕÖ¾ÓòÃû

¶ÔÓÚÈÕÖ¾Éϱ¨Ê¹Óõ¥¶ÀµÄÈÕÖ¾ÓòÃûµÄÄ¿µÄÊDZÜÃâ¶ÔÒµÎñÔì³ÉÓ°Ïì¡£ÆäÒ»£¬¶ÔÓÚ·þÎñÆ÷À´Ëµ£¬ÎÒÃǿ϶¨²»Ï£ÍûÕ¼ÓÃÒµÎñ·þÎñÆ÷µÄ¼ÆËã×ÊÔ´£¬Ò²²»Ï£Íû¹ý¶àµÄÈÕÖ¾ÔÚÒµÎñ·þÎñÆ÷¶Ñ»ý£¬Ôì³ÉÒµÎñ·þÎñÆ÷µÄ´æ´¢¿Õ¼ä²»¹»µÄÇé¿ö¡£Æä¶þ£¬ÎÒÃÇÖªµÀÔÚÒ³Ãæ³õʼ»¯µÄ¹ý³ÌÖУ¬»á¶ÔÒ³Ãæ¼ÓÔØÊ±¼ä¡¢PV¡¢UVµÈÊý¾Ý½øÐÐÉϱ¨£¬ÕâЩÉϱ¨ÇëÇó»áºÍ¼ÓÔØÒµÎñÊý¾Ý¼¸ºõÊÇͬʱ¿Ì·¢³ö£¬¶øä¯ÀÀÆ÷Ò»°ã»á¶Ôͬһ¸öÓòÃûµÄÇëÇóÁ¿Óв¢·¢ÊýµÄÏÞÖÆ£¬Èç Chrome»áÓжԲ¢·¢ÊýΪ 6¸öµÄÏÞÖÆ¡£Òò´ËÐèÒª¶ÔÈÕ־ϵͳµ¥¶ÀÉ趨ÓòÃû£¬×îС»¯¶ÔÒ³Ãæ¼ÓÔØÐÔÄÜÔì³ÉµÄÓ°Ïì¡£

¿çÓòµÄÎÊÌâ

¶ÔÓÚµ¥¶ÀµÄÈÕÖ¾ÓòÃû£¬¿Ï¶¨»áÉæ¼°µ½¿çÓòµÄÎÊÌ⣬²ÉÈ¡µÄ½â¾ö·½°¸Ò»°ãÓÐÒÔÏÂÁ½ÖÖ£º

Ò»ÖÖÊǹ¹Ôì¿ÕµÄ Image¶ÔÏóµÄ·½Ê½£¬ÆäÔ­ÒòÊÇÇëÇóͼƬ²¢²»Éæ¼°µ½¿çÓòµÄÎÊÌ⣻

var url = 'xxx';
new Image().src = url;

ÀûÓà AjaxÉϱ¨ÈÕÖ¾£¬±ØÐë¶ÔÈÕÖ¾·þÎñÆ÷½Ó¿Ú¿ªÆô¿çÓòÇëÇóÍ·²¿ Access-Control-Allow-Origin:*£¬ÕâÀï Ajax¾Í²¢²»Ç¿ÖÆÊ¹Óà GETÇëÇóÁË£¬¼´¿É¿Ë·þ URL³¤¶ÈÏÞÖÆµÄÎÊÌâ¡£

if (XMLHttpRequest) {
var xhr = new XMLHttpRequest();
xhr.open('post', 'https://log.xxx.com', true); // Éϱ¨¸ønodeÖмä²ã´¦Àí
xhr.setRequestHeader('Content-Type', 'application/json'); // ÉèÖÃÇëÇóÍ·
xhr.send(JSON.stringify(errorObj)); // ·¢ËͲÎÊý
}

ÔÚÎÒµÄÏîÄ¿ÖÐʹÓõÄÊǵÚÒ»Öֵķ½Ê½£¬Ò²¾ÍÊǹ¹Ôì¿ÕµÄ Image¶ÔÏ󣬵«ÊÇÎÒÃÇÖªµÀ¶ÔÓÚ GETÇëÇó»áÓг¤¶ÈµÄÏÞÖÆ£¬ÐèҪȷ±£µÄÊÇÇëÇóµÄ³¤¶È²»»á³¬¹ýãÐÖµ¡£

ʡȥÏìÓ¦Ö÷Ìå

¶ÔÓÚÎÒÃÇÉϱ¨ÈÕÖ¾£¬Æäʵ¶ÔÓÚ¿Í»§¶ËÀ´Ëµ£¬²¢²»ÐèÒª¿¼ÂÇÉϱ¨µÄ½á¹û£¬ÉõÖÁ¶ÔÓÚÉϱ¨Ê§°Ü£¬ÎÒÃÇÒ²²»ÐèÒªÔÚǰ¶Ë×öÈκν»»¥£¬ËùÒÔÉϱ¨À´Ëµ£¬ÆäʵʹÓà HEADÇëÇó¾Í¹»ÁË£¬½Ó¿Ú·µ»Ø¿ÕµÄ½á¹û£¬×î´óµØ¼õÉÙÉϱ¨ÈÕÖ¾Ôì³ÉµÄ×ÊÔ´ÀË·Ñ¡£

ºÏ²¢Éϱ¨

ÀàËÆÓÚÑ©±ÌͼµÄ˼Ï룬Èç¹ûÎÒÃǵÄÓ¦ÓÃÐèÒªÉϱ¨µÄÈÕÖ¾ÊýÁ¿ºÜ¶à£¬ÄÇôÓбØÒªºÏ²¢ÈÕÖ¾½øÐÐͳһµÄÉϱ¨¡£

½â¾ö·½°¸¿ÉÒÔÊdz¢ÊÔÔÚÓû§Àë¿ªÒ³Ãæ»òÕß×é¼þÏú»Ùʱ·¢ËÍÒ»¸öÒì²½µÄ POSTÇëÇóÀ´½øÐÐÉϱ¨£¬µ«Êdz¢ÊÔÔÚÐ¶ÔØ£¨ unload£©ÎĵµÖ®Ç°Ïò web·þÎñÆ÷·¢ËÍÊý¾Ý¡£±£Ö¤ÔÚÎĵµÐ¶ÔØÆÚ¼ä·¢ËÍÊý¾ÝÒ»Ö±ÊÇÒ»¸öÀ§ÄÑ¡£ÒòΪÓû§´úÀíͨ³£»áºöÂÔÔÚÐ¶ÔØÊ¼þ´¦ÀíÆ÷ÖвúÉúµÄÒì²½ XMLHttpRequest£¬ÒòΪ´ËʱÒѾ­»áÌø×ªµ½ÏÂÒ»¸öÒ³Ãæ¡£ËùÒÔÕâÀïÊDZØÐëÉèÖÃΪͬ²½µÄ XMLHttpRequestÇëÇóÂð£¿

window.addEventListener('unload', logData, false);

function logData() {
var client = new XMLHttpRequest();
client.open("POST", "/log", false); // µÚÈý¸ö²ÎÊý±íÃ÷ÊÇͬ²½µÄ xhr
client.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
client.send(analyticsData);
}

ʹÓÃͬ²½µÄ·½Ê½ÊƱػá¶ÔÓû§ÌåÑéÔì³ÉÓ°Ï죬ÉõÖÁ»áÈÃÓû§¸ÐÊܵ½ä¯ÀÀÆ÷¿¨ËÀ¸Ð¾õ£¬¶ÔÓÚ²úÆ·¶øÑÔ£¬ÌåÑé·Ç³£²»ºÃ£¬Í¨¹ý²éÔÄMDNÎĵµ£¬¿ÉÒÔʹÓà sendBeacon()·½·¨£¬½«»áʹÓû§´úÀíÔÚÓлú»áʱÒì²½µØÏò·þÎñÆ÷·¢ËÍÊý¾Ý£¬Í¬Ê±²»»áÑÓ³ÙÒ³ÃæµÄÐ¶ÔØ»òÓ°ÏìÏÂÒ»µ¼º½µÄÔØÈëÐÔÄÜ¡£Õâ¾Í½â¾öÁËÌá½»·ÖÎöÊý¾ÝʱµÄËùÓеÄÎÊÌ⣺ʹËü¿É¿¿£¬Òì²½²¢ÇÒ²»»áÓ°ÏìÏÂÒ»Ò³ÃæµÄ¼ÓÔØ¡£´ËÍ⣬´úÂëʵ¼ÊÉÏ»¹Òª±ÈÆäËû¼¼Êõ¼òµ¥£¡

ÏÂÃæµÄÀý×ÓչʾÁËÒ»¸öÀíÂÛÉϵÄͳ¼Æ´úÂëģʽ¡ª¡ªÍ¨¹ýʹÓà sendBeacon()·½·¨Ïò·þÎñÆ÷·¢ËÍÊý¾Ý¡£

window.addEventListener('unload', logData, false);

function logData() {
navigator.sendBeacon("/log", analyticsData);
}

С½á

×÷Ϊǰ¶Ë¿ª·¢Õß¶øÑÔ£¬Òª¶Ô²úÆ·±£³Ö¾´Î·Ö®ÐÄ£¬Ê±¿Ì±£³Ö¶ÔÐÔÄÜ×·Çó¼«Ö£¬¶ÔÒì³£²»¿ÉÈÝÈ̵Ä̬¶È¡£Ç°¶ËµÄÐÔÄÜ¼à¿ØÓëÒì³£Éϱ¨ÏÔµÃÓÈÎªÖØÒª¡£

´úÂëÄÑÃâÓÐÎÊÌ⣬¶ÔÓÚÒì³£¿ÉÒÔʹÓà window.onerror»òÕß addEventListenerµÄ·½Ê½Ìí¼ÓÈ«¾ÖµÄÒì³£²¶»ñÕìÌýº¯Êý£¬µ«¿ÉÄÜʹÓÃÕâÖÖ·½Ê½ÎÞ·¨ÕýÈ·²¶»ñµ½´íÎ󣺶ÔÓÚ¿çÓòµÄ½Å±¾£¬ÐèÒª¶Ô script±êÇ©Ôö¼ÓÒ»¸ö crossorigin=¡±anonymous¡±£»¶ÔÓÚÉú²ú»·¾³´ò°üµÄ´úÂ룬ÎÞ·¨ÕýÈ·¶¨Î»µ½Òì³£²úÉúµÄÐÐÊý£¬¿ÉÒÔʹÓà source-mapÀ´½â¾ö£»¶ø¶ÔÓÚʹÓÿò¼ÜµÄÇé¿ö£¬ÐèÒªÔÚ¿ò¼ÜͳһµÄÒì³£²¶»ñ´¦Âñµã¡£

¶ø¶ÔÓÚÐÔÄÜµÄ¼à¿Ø£¬ËùÐÒµÄÊÇä¯ÀÀÆ÷ÌṩÁË window.performance API£¬Í¨¹ýÕâ¸ö API£¬ºÜ±ã½ÝµØ»ñÈ¡µ½µ±Ç°Ò³ÃæÐÔÄÜÏà¹ØµÄÊý¾Ý¡£

¶øÕâЩÒì³£ºÍÐÔÄÜÊý¾ÝÈçºÎÉϱ¨ÄØ£¿Ò»°ã˵À´£¬ÎªÁ˱ÜÃâ¶ÔÒµÎñ²úÉúµÄÓ°Ï죬»áµ¥¶À½¨Á¢ÈÕÖ¾·þÎñÆ÷ºÍÈÕÖ¾ÓòÃû£¬µ«¶ÔÓÚ²»Í¬µÄÓòÃû£¬ÓÖ»á²úÉú¿çÓòµÄÎÊÌâ¡£ÎÒÃÇ¿ÉÒÔͨ¹ý¹¹Ôì¿ÕµÄ Image¶ÔÏóÀ´½â¾ö£¬Òà»òÊÇͨ¹ýÉ趨¿çÓòÇëÇóÍ·²¿ Access-Control-Allow-Origin:*À´½â¾ö¡£´ËÍ⣬Èç¹ûÉϱ¨µÄÐÔÄܺÍÈÕÖ¾Êý¾Ý¸ßƵ´¥·¢£¬Ôò¿ÉÒÔÔÚÒ³Ãæ unloadʱͳһÉϱ¨£¬¶ø unloadʱµÄÒì²½ÇëÇóÓÖ¿ÉÄܻᱻä¯ÀÀÆ÷ËùºöÂÔ£¬ÇÒ²»ÄܸÄΪͬ²½ÇëÇó¡£´Ëʱ navigator.sendBeacon API¿ÉËã°ïÁËÎÒÃÇ´óæ£¬Ëü¿ÉÓÃÓÚͨ¹ý HTTP½«ÉÙÁ¿Êý¾ÝÒì²½´«Êäµ½ Web·þÎñÆ÷¡£¶øºöÂÔÒ³Ãæ unloadʱµÄÓ°Ïì¡£

Ïà¹ØÎÄÕÂ

Éî¶È½âÎö£ºÇåÀíÀôúÂë
ÈçºÎ±àд³öÓµ±§±ä»¯µÄ´úÂë
ÖØ¹¹-ʹ´úÂë¸ü¼ò½àÓÅÃÀ
ÍŶÓÏîÄ¿¿ª·¢"±àÂë¹æ·¶"ϵÁÐÎÄÕÂ
Ïà¹ØÎĵµ

ÖØ¹¹-¸ÄÉÆ¼ÈÓдúÂëµÄÉè¼Æ
Èí¼þÖØ¹¹v2
´úÂëÕû½àÖ®µÀ
¸ßÖÊÁ¿±à³Ì¹æ·¶
Ïà¹Ø¿Î³Ì

»ùÓÚHTML5¿Í»§¶Ë¡¢Web¶ËµÄÓ¦Óÿª·¢
HTML 5+CSS ¿ª·¢
ǶÈëʽC¸ßÖÊÁ¿±à³Ì
C++¸ß¼¶±à³Ì

   
2613 ´Îä¯ÀÀ       27