«Упаковка собственных разработанных библиотек JS с использованием модульных инструментов»Как упоминалось в статье, в то время необходимо было написать SDK для мониторинга фоновых обращений к интерфейсу и страничных ошибок апплета.Сегодня поговорим о принципе реализации!
принцип
Я также делал отчеты о скрытых точках данных SDK на веб-стороне браузера. Фактически, принцип аналогичен: путем захвата исходного метода получаются данные для отчета, и, наконец, исходный метод выполняется, так что бесследная погребенная точка может быть реализована.
Например: я хочу отслеживать ajax-запросы всех веб-страниц.Каждый раз, когда я отправляю ajax, мне нужно распечатать отправленный URL-адрес на консоли.
Обычно мы разрабатываем и отправляем ajax с помощью упакованных библиотек, таких как jQuery, Axios и т. д. Однако эти библиотеки по-прежнему используют собственный объект браузера XMLHttpRequest внизу, поэтому нам нужно только изменить объект XMLHttpRequest.
Примечание. Из-за гибкости JS нативные методы легко модифицировать, однако это не рекомендуется!
// 把这段代码放在所有JS代码之前,我们就实现了拦截ajax的需求
window.XMLHttpRequest.prototype.open = (function(originOpen) {
return function(method, url, async) {
console.log('发送了ajax,url是: ', url);
return originOpen.apply(this, arguments);
};
})(window.XMLHttpRequest.prototype.open);
В эту непосредственную функцию мы поместили нативнуюopen
метод переданoriginOpen
Временно сохраните его, а затем оберните слой функции снаружи, чтобы реализовать функцию печати и вывода URL-адреса, и, наконец, передайтеoriginOpen.apply
Позвольте собственному методу работать, тем самым добившись плавного перехвата.
Апплет мониторинга
Перехват wx.request
Операционная среда апплета неwindow
а такжеdocument
объект, который выставляет толькоwx
Глобальный объект, отправка сетевых запросов осуществляется черезwx.requestЭто API, так что нам нужно перехватить на этот разwx.request
метод
Давай попробуем изменитьwx.request
wx.request = function() {
console.log('66666');
}
В это время консоль сообщит об ошибкеTypeError: Cannot set property request of #<Object> which has only a getter
Это потому что,wx.request
Это свойство, толькоget
метод безset
метод, мы можем пройтиObject.getOwnPropertyDescriptor
проверять:
const des = Object.getOwnPropertyDescriptor(wx, 'request');
// des {
// configurable: true,
// enumerable: true,
// get: f(),
// set: undefined
// }
Мы можем изменить его по-другому:
const originRequest = wx.request;
Object.defineProperty(wx, 'request', {
configurable: true,
enumerable: true,
writable: true,
value: function() {
const config = arguments[0] || {};
const url = config.url;
console.log('发送了ajax,url是: ', url);
return originRequest.apply(this, arguments);
}
});
На этот раз реализована функция перехвата!
Отслеживание исключений
Функция регистрации малых программApp
иметь глобальныйonError
метод, мы можем поместить его в файл ввода апплетаapp.js
Сначала зарегистрируйте этот метод:
App({
onError: function(err) {
console.log('上报错误啦!');
wx.request({
url: 'http://monitor.com/monitor/error',
data: err
})
}
})
App({
// 其他逻辑
})
Однако следует отметить, что если последующая программа перезапишет onError, ранее зарегистрированная onError будет недействительной.
Решение может быть таким: мы отслеживаем SDK, чтобы выставить интерфейс, и позволяем стороне доступа вызывать наш интерфейс в onError.
App({
onError: function (err) {
monitor.notifyError(err)
}
})
данные отчета
После сбора требуемых данных, конечно же, необходимо сообщить об этом фону. Как сообщить? конечно еще б/уwx.request
послать запрос.
Вот простойбесконечная петля: Если вы используете пакет, который мы упаковали ранееwx.request
Отчетные данные, то запрос ajax на отчетные данные также будет рассматриваться как обычный запрос ajax, а затем инициировать отчет, так что вперед и назад, бесконечно отправляя данные отчета.
Существуют различные решения, такие как:
план 1
доступен в упаковкеwx.request
Когда будет установлено, что отправленный URL-адрес является интерфейсом отчетов, о нем больше не будет сообщаться.
const originRequest = wx.request;
Object.defineProperty(wx, 'request', {
configurable: true,
enumerable: true,
writable: true,
value: function() {
const config = arguments[0] || {};
const url = config.url;
if (url.indexOf('http://monitor.com') > -1) {
// 直接发送请求,不上报
return originRequest.apply(this, arguments);
}
console.log('上报ajax数据啦!');
wx.request({
url: 'http://monitor.com/monitor/ajax',
data: config.data
})
return originRequest.apply(this, arguments);
}
});
Сценарий 2
в упаковкеwx.request
Прежде сохраняйте копию оригиналаwx.request
метод, все запросы отчетов следуют не обернутому методу, а самому примитивному методу.
const myRequest = wx.request;
const wrapRequest = function () {
const originRequest = wx.request;
Object.defineProperty(wx, 'request', {
configurable: true,
enumerable: true,
writable: true,
value: function() {
const config = arguments[0] || {};
const url = config.url;
console.log('上报数据啦!');
// 使用最原始的request方法
myRequest({
url: 'http://monitor.com/monitor/ajax',
data: config.data
})
return originRequest.apply(this, arguments);
}
});
}
wrapRequest();
что-то другое
Конечно, в фактической разработке больше деталей, таких как аутентификация проекта мониторинга, структура кода SDK, сбор и агрегация данных перед отчетностью и т. д., которые не будут подробно описываться в этой статье.