diff --git a/addon/web/client/src/components/ViewFlow.tsx b/addon/web/client/src/components/ViewFlow.tsx index 5929a8f..4d99554 100644 --- a/addon/web/client/src/components/ViewFlow.tsx +++ b/addon/web/client/src/components/ViewFlow.tsx @@ -24,6 +24,26 @@ class ViewFlow extends React.Component { } } + preview() { + const { flow } = this.props + if (!flow) return null + const response = flow.response + if(!response) return null + + if (!(response.body && response.body.byteLength)) { + return
No response
+ } + + const pv = flow.previewResponseBody() + if (!pv) return
Not support preview
+ + if (pv.type === 'image') { + return + } + + return
Not support preview
+ } + render() { if (!this.props.flow) return null @@ -136,6 +156,11 @@ class ViewFlow extends React.Component { {flow.responseBody()} } + + { + !(flowTab === 'Preview') ? null : +
{this.preview()}
+ } diff --git a/addon/web/client/src/message.ts b/addon/web/client/src/message.ts index 18bdb22..4d18d93 100644 --- a/addon/web/client/src/message.ts +++ b/addon/web/client/src/message.ts @@ -1,4 +1,4 @@ -import { getSize, isTextBody } from './utils' +import { arrayBufferToBase64, getSize, isTextBody } from './utils' export enum MessageType { REQUEST = 1, @@ -42,6 +42,11 @@ export interface IFlowPreview { costTime: string } +interface IPreviewResponseBody { + type: 'image' + data: string +} + export class Flow { public no: number public id: string @@ -68,6 +73,8 @@ export class Flow { private _requestBody: string | null private _responseBody: string | null + private _previewResponseBody: IPreviewResponseBody | null = null + constructor(msg: IMessage) { this.no = ++Flow.curNo this.id = msg.id @@ -167,6 +174,26 @@ export class Flow { this._responseBody = new TextDecoder().decode(this.response?.body) return this._responseBody } + + public previewResponseBody(): IPreviewResponseBody | null { + if (this._previewResponseBody) return this._previewResponseBody + + if (this.status < MessageType.RESPONSE_BODY) return null + if (!(this.response?.body?.byteLength)) return null + + let contentType: string | undefined + if (this.response.header['Content-Type']) contentType = this.response.header['Content-Type'][0] + if (!contentType) return null + + if (contentType.startsWith('image/')) { + this._previewResponseBody = { + type: 'image', + data: arrayBufferToBase64(this.response.body), + } + } + + return this._previewResponseBody + } } const allMessageBytes = [ diff --git a/addon/web/client/src/utils.ts b/addon/web/client/src/utils.ts index 813b008..2865a13 100644 --- a/addon/web/client/src/utils.ts +++ b/addon/web/client/src/utils.ts @@ -31,3 +31,13 @@ export const shallowEqual = (objA: any, objB: any) => { } return true } + +export const arrayBufferToBase64 = (buf: ArrayBuffer) => { + let binary = '' + const bytes = new Uint8Array(buf) + const len = bytes.byteLength + for (let i = 0; i < len; i++) { + binary += String.fromCharCode(bytes[i]) + } + return btoa(binary) +}