diff --git a/CHANGELOG.md b/CHANGELOG.md index f88bb55a..918e17c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ English | [简体中文](./CHANGELOG_CN.md) +## 3.14.0 (2022-03-23) + +- `Feat(Core)` Add new option `pluginOrder` to adjust the order of built-in and custom plugins, see [Public Properties & Methods](./doc/public_properties_methods.md). +- `Feat(Core)` Panel will auto scroll to previous position when switching plugin panel. +- `Feat(Network)` Add response size. +- `Feat(Network)` Add support for `transfer-encoding: chunked`, now streaming response can be recorded. +- `Feat(Network)` Improve rendering performance of large Response data by cropping the displayed response content. +- `Refactor(Network)` Now network records will be more accurate by using Proxy to prevent `XMLHttpRequest | fetch` overwriting by other request libraries (like Axios). + + ## 3.13.0 (2022-03-15) - `Feat(Log)` Add new option `log.showTimestames`, see [Public Properties & Methods](./doc/public_properties_methods.md). diff --git a/CHANGELOG_CN.md b/CHANGELOG_CN.md index 61108d8a..7569ed31 100644 --- a/CHANGELOG_CN.md +++ b/CHANGELOG_CN.md @@ -1,5 +1,15 @@ [English](./CHANGELOG.md) | 简体中文 +## 3.14.0 (2022-03-23) + +- `Feat(Core)` 新增配置项 `pluginOrder` 来调整插件面板的排序,见 [公共属性及方法](./doc/public_properties_methods_CN.md)。 +- `Feat(Core)` 切换插件面板时,面板会自动滚动到上次的位置。 +- `Feat(Network)` 新增显示 Response 的体积。 +- `Feat(Network)` 新增对 `transfer-encoding: chunked` 的支持,现在可记录流式回包(stream response)。 +- `Feat(Network)` 展示时裁剪过大的 Response 回包以提高渲染性能。 +- `Refactor(Network)` 提高网络记录的准确性,以避免被外部库(如 Axios)覆盖;方法是对 `XMLHttpRequest | fetch` 使用 Proxy。 + + ## 3.13.0 (2022-03-15) - `Feat(Log)` 新增配置项 `log.showTimestames`,见 [公共属性及方法](./doc/public_properties_methods_CN.md)。 diff --git a/dev/network.html b/dev/network.html index 09ff2056..67382d43 100644 --- a/dev/network.html +++ b/dev/network.html @@ -7,8 +7,8 @@ - +
@@ -19,6 +19,7 @@ POST XHR (Data: Object) POST XHR (Data: JSON String) OPTIONS XHR + XHR Stream
@@ -33,6 +34,7 @@ POST Fetch Using XHR OPTIONS Fetch Fetch iOS LowBug + Fetch Steam
@@ -131,6 +133,7 @@ } function getFetch() { + vConsole.show(); window.fetch('./data/success.json?method=fetchGet&id=' + Math.random(), { method: 'GET', headers: { @@ -138,9 +141,16 @@ 'content-type': 'application/json' }, }).then((data) => { - return data.json(); + console.log('getFetch() response:', data); + setTimeout(() => { + data.json().then((res) => { + console.log(res); + }); + }, 3000); + // return data; + // return data.json(); }).then((data) => { - console.log('get Fetch Response:', data); + // console.log('getFetch() json:', data); }); } @@ -161,7 +171,6 @@ }); } - function getFetchSimple() { window.fetch('./data/large.json?type=fetchGet&id=' + Math.random()).then((data) => { return data.json(); @@ -256,6 +265,74 @@ }); } +function fetchStream() { + vConsole.show(); + window.fetch('./data/stream.flv?id=' + Math.random()).then((response) => { + console.log('then response', 'bodyUsed:', response.bodyUsed, 'locked:', response.body.locked); + // console.log(response.text()) + // return; + const reader = response.body.getReader(); + console.log('then response', 'bodyUsed:', response.bodyUsed, 'locked:', response.body.locked); + let bytesReceived = 0; + + return reader.read().then(function process(result) { + console.log('reader.read', 'bodyUsed:', response.bodyUsed, 'locked:', response.body.locked); + if (result.done) { + console.log('Failed to find match'); + return; + } + + bytesReceived += result.value.length; + console.log(`Received ${bytesReceived} bytes.`); + + if (bytesReceived > 3000000) { + reader.cancel(); + console.log('Cancel.', response.status); + return; + } + + return reader.read().then(process); + }); + }); +} + +function xhrStream() { + vConsole.show(); + const url = './data/stream.flv?id=' + Math.random(); + const xhr = new XMLHttpRequest(); + xhr.timeout = 11000; + console.log('xhr type:', typeof xhr, xhr instanceof XMLHttpRequest); + xhr.open('GET', url); + xhr.send(); + xhr.onreadystatechange = () => { + console.log('XHR onreadystatechange:', 'readyState:', xhr.readyState, 'responseType:', xhr.responseType); + }; + xhr.onprogress = (e) => { + // console.log('XHR onprogress:', 'readyState:', xhr.readyState, 'status:', xhr.status, 'loaded:', e.loaded, 'timeStamp:', e.timeStamp); + if (e.loaded > 3000000) { + xhr.abort(); + } + }; + xhr.onloadstart = (e) => { + // console.log('XHR onloadstart:', e); + }; + xhr.onloadend = (e) => { + // console.log('XHR onloadend:', 'readyState:', xhr.readyState, xhr.status, e); + }; + xhr.onload = (e) => { + console.log('XHR onload:', 'readyState:', xhr.readyState, xhr.status, xhr.responseType); + }; + xhr.onerror = (e) => { + console.log('XHR onerror:', e); + }; + xhr.onabort = (e) => { + console.log('XHR onabort:', xhr.readyState, xhr.status, e); + }; + xhr.ontimeout = (e) => { + console.log('XHR ontimeout:', e); + } +} + function postImage() { console.info('postImage() Start, response should be logged after End'); const xhr = new XMLHttpRequest(); @@ -269,6 +346,7 @@ } function sendBeacon() { + vConsole.show(); console.info('sendBeacon() Start, response should be logged after End'); window.navigator.sendBeacon('./data/success.json?method=beacon', JSON.stringify({ foo: 'bar', @@ -297,16 +375,6 @@ console.info('axiosRequest() End'); } -function sendBeacon() { - console.info('sendBeacon() Start, response should be logged after End'); - window.navigator.sendBeacon('./data/success.json?method=beacon', JSON.stringify({ - foo: 'bar', - id: Math.random(), - type: 'sendBeacon' - })); - console.info('sendBeacon() End'); -} - function axiosRequest(method) { console.info('axiosRequest() Start'); axios({ diff --git a/dev/plugin.html b/dev/plugin.html index 83873eee..b9b7e760 100644 --- a/dev/plugin.html +++ b/dev/plugin.html @@ -25,18 +25,13 @@