@conecli/cone-render 0.9.1-shop2.30 → 0.9.1-shop2.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- import Taro from '@tarojs/taro'
2
1
  isSupportHybridHttpRequest,
3
2
  draInterfaceCustomReport,
4
3
  draBusinessCustomReport,
5
4
  jsonHeader = 'application/json;charset=utf-8',
6
5
  formDataHeader = 'application/x-www-form-urlencoded',
7
6
  HYBRID: 'httpRequest_hybrid',
8
7
  TARO: 'httpRequest_taro',
9
8
  #requestTimeStamp: number
10
9
  #responseTimeStamp: number
11
10
  #getResTimeStamp: number
12
11
  #reportType: string
13
12
  #callbackFunction: string
14
13
 
15
14
  async request({
16
15
  url,
17
16
  method = 'POST',
18
17
  timeout = 7000,
19
18
  isColorVerify = false,
20
19
  ...otherOptions
21
20
  }): Promise<Taro.request.SuccessCallbackResult<any>> {
22
21
  const { header: otherHeader, ...otherOpts } = otherOptions
23
22
  const header = {
24
23
  'content-type':
25
24
  method === 'POST'
26
25
  ? RequestHeaderContentType.formDataHeader
27
26
  : RequestHeaderContentType.jsonHeader,
28
27
  ...otherHeader,
29
28
  }
30
29
  let getRequestUrl = url
31
30
  let requestTask
32
31
  const data = otherOpts?.data
33
32
  const isGatewayRequest =
34
33
  url === this.api.apiFunc && typeof data === 'object'
35
34
  if (isGatewayRequest) {
36
35
  getRequestUrl = this._handleSpecialGatewayUrl(url)
37
36
  const shouldUseHybridRequest = this._shouldUseHybridRequest()
38
37
  if (shouldUseHybridRequest) {
39
38
  requestTask = this._hybridRequest(getRequestUrl, data)
40
39
  } else {
41
40
  otherOpts.data = await this._prepareGatewayReqData(data, isColorVerify)
42
41
  requestTask = this._taroRequest(
43
42
  getRequestUrl,
44
43
  otherOpts,
45
44
  method,
46
45
  timeout,
47
46
  header,
48
47
  )
49
48
  }
50
49
  } else {
51
50
  requestTask = this._taroRequest(
52
51
  getRequestUrl,
53
52
  otherOpts,
54
53
  method,
55
54
  timeout,
56
55
  header,
57
56
  )
58
57
  }
59
58
  const requestTimeoutPromise =
60
59
  new Promise<ServiceInterFace.RequestPromiseRes>((resolve) => {
61
60
  setTimeout(() => {
62
61
  resolve({
63
62
  statusCode: 500,
64
63
  resTimeoutState: true,
65
64
  errMsg: 'request timeout',
66
65
  })
67
66
  }, timeout)
68
67
  })
69
68
  return Promise.race([requestTask, requestTimeoutPromise]).then(
70
69
  (res: any) => {
71
70
  if (res && res.statusCode === 500 && res.resTimeoutState) {
72
71
  if (this.#reportType === HTTP_REQUEST_TYPE.HYBRID) {
73
72
  this._clearFunction(this.#callbackFunction)
74
73
  } else {
75
74
  requestTask.abort && requestTask.abort()
76
75
  }
77
76
  }
78
77
  this._handleReportInterfaceError(url, data, timeout, res)
79
78
  return res
80
79
  },
81
80
  )
82
81
  }
83
82
 
84
83
  _handleSpecialGatewayUrl(url: string): string {
85
84
  if (isPc && window.location.hostname.includes('.jd.hk')) {
86
85
  return this.api.hkApiFunc
87
86
  }
88
87
  if (
89
88
  isJdApp &&
90
89
  window?.shopGlobalSwitch?.dualProtocol &&
91
90
  !window.location.href.includes('jshopx_vconsole')
92
91
  ) {
93
92
  return window?.shopGlobalSwitch?.dualProtocol?.apiTestApp || url
94
93
  }
95
94
  return url
96
95
  }
97
96
 
98
97
  _shouldUseHybridRequest(): boolean {
99
98
  try {
100
99
  if (!isJdApp || !isSupportHybridHttpRequest || isJdAndHarmonyDevice) {
101
100
  return false
102
101
  }
103
102
  const configData = global.getDynamicConfig('hybridHttpSwitch')
104
103
  const { globalOn = false, grayscale = {} } = configData || {}
105
104
  const buildType = process.env.BUILD_TYPE || ''
106
105
  const isInvokeGray = globalOn || grayscale[buildType]
107
106
  console.log(
108
107
  '使用hybrid请求是否命中灰度,isInvokeGray:',
109
108
  isInvokeGray,
110
109
  '获取mpaas配置hybridHttpSwitch原始数据configData',
111
110
  configData,
112
111
  )
113
112
  const hasWindowXWebView = !!window.XWebView
114
113
  return isInvokeGray && hasWindowXWebView
115
114
  } catch (e) {
116
115
  console.log('获取是否使用Hybrid请求出错,e:', e)
117
116
  return false
118
117
  }
119
118
  }
120
119
 
121
120
  _hybridRequest(url: string, data: any): Promise<any> {
122
121
  return new Promise((resolve, reject) => {
123
122
  try {
124
123
  const changeCurrentUrl = url.startsWith('//') ? `https:${url}` : url
125
124
  const { functionId, body, ...otherH5Param } = data
126
125
  const reqParams = {
127
126
  url: isIosDevice ? `${changeCurrentUrl}/` : changeCurrentUrl,
128
127
  functionId: functionId,
129
128
  body: body,
130
129
  headerType: '0',
131
130
  param: {
132
131
  ...otherH5Param,
133
132
  },
134
133
  header: {
135
134
  Referer: window.location.origin,
136
135
  },
137
136
  }
138
137
  const callbackFunction = this._generateCallbackFunction()
139
138
  this.#callbackFunction = callbackFunction
140
139
  this.#requestTimeStamp = Date.now()
141
140
  this.#reportType = HTTP_REQUEST_TYPE.HYBRID
142
141
  window.XWebView.callNative(
143
142
  'ColorQueryPlugin',
144
143
  'colorRequest',
145
144
  JSON.stringify(reqParams),
146
145
  callbackFunction,
147
146
  '1',
148
147
  )
149
148
  window[callbackFunction] = (result) => {
150
149
  this.#responseTimeStamp = Date.now()
151
150
  try {
152
151
  const resultObj =
153
152
  typeof result === 'string' ? JSON.parse(result) : result
154
153
  resolve(resultObj)
155
154
  } catch (error) {
156
155
  const errMsg = 'hybrid网络请求JSON解析失败, error: ' + error
157
156
  draBusinessCustomReport({
158
157
  type: `${HTTP_REQUEST_TYPE.HYBRID}_jsonParseError`,
159
158
  errMsg,
160
159
  result,
161
160
  })
162
161
  reject({ errMsg })
163
162
  }
164
163
  this._clearFunction(callbackFunction)
165
164
  }
166
165
  } catch (error) {
167
166
  reject({
168
167
  errMsg:
169
168
  'hybrid网络请求,App下调用window.XWebView.callNative出错, error: ' +
170
169
  error,
171
170
  })
172
171
  }
173
172
  })
174
173
  }
175
174
 
176
175
  _generateCallbackFunction() {
177
176
  return `hybridHttpRequestCallback_${Date.now()}_${Math.ceil(
178
177
  Math.random() * 100000,
179
178
  )}`
180
179
  }
181
180
 
182
181
  _clearFunction(functionName: string) {
183
182
  try {
184
183
  delete window[functionName]
185
184
  } catch (e) {
186
185
  window[functionName] = undefined
187
186
  }
188
187
  }
189
188
 
190
189
  async _prepareGatewayReqData(
191
190
  data: any,
192
191
  isColorVerify: boolean,
193
192
  ): Promise<any> {
194
193
  const { functionId } = data
195
194
  console.log('获取当前是否需要color加固', isColorVerify, functionId)
196
195
  if (isColorVerify) {
197
196
  const { h5st } = await colorSign.paramsSign(data)
198
197
  h5st && (data.h5st = encodeURI(h5st))
199
198
  console.log(`${functionId}的apiReq_h5st===>:${h5st}`)
200
199
  }
201
200
  const { jsToken } = await colorSign.getFmInfo()
202
201
  console.log(`${functionId}的api jsToken指纹===>:${jsToken}`)
203
202
  jsToken && (data['x-api-eid-token'] = jsToken)
204
203
  return data
205
204
  }
206
205
 
207
206
  _taroRequest(
208
207
  url: string,
209
208
  otherOpts: any,
210
209
  method: string,
211
210
  timeout: number,
212
211
  header: string,
213
212
  ): Promise<any> {
214
213
  const reqParam = {
215
214
  url,
216
215
  method,
217
216
  timeout,
218
217
  header,
219
218
  credentials: 'include',
220
219
  ...otherOpts,
221
220
  }
222
221
  this.#requestTimeStamp = Date.now()
223
222
  this.#reportType = HTTP_REQUEST_TYPE.TARO
224
223
  return Taro.request(reqParam)
225
224
  }
226
225
 
227
226
  _reportRequestTime(url: string, data: any): void {
228
227
  this.#getResTimeStamp = Date.now()
229
228
  if (this.#reportType === HTTP_REQUEST_TYPE.TARO) {
230
229
  this.#responseTimeStamp = this.#getResTimeStamp
231
230
  }
232
231
  draInterfaceCustomReport(
233
232
  {
234
233
  type: `${this.#reportType}_consumeTime`,
235
234
  url,
236
235
  functionId: data?.functionId,
237
236
  requestTimeStamp: this.#requestTimeStamp,
238
237
  responseTimeStamp: this.#responseTimeStamp,
239
238
  errMsg: `使用${this.#reportType}调用接口请求响应耗时`,
240
239
  source: 'remote',
241
240
  },
242
241
  {
243
242
  consumeTime: `${this.#responseTimeStamp - this.#requestTimeStamp}ms`,
244
243
  getResTime: `${this.#getResTimeStamp - this.#requestTimeStamp}ms`,
245
244
  },
246
245
  )
247
246
  }
248
247
 
249
248
  _handleReportInterfaceError(
250
249
  url: string,
251
250
  reqData: any,
252
251
  timeOut: any,
253
252
  res: any,
254
253
  ): void {
255
254
  const source = 'remote'
256
255
  const requestType = this.#reportType
257
256
  let errorType = ''
258
257
  let subMsg = ''
259
258
  let reportFlag = false
260
259
  if (res) {
261
260
  const { statusCode, data, status, resTimeoutState } = res
262
261
  if (statusCode === 500 && resTimeoutState) {
263
262
  reportFlag = true
264
263
  errorType = 'timeout'
265
264
  subMsg = `接口请求超时${timeOut}ms`
266
265
  } else if ((statusCode === 200 || status === '0') && data) {
267
266
  const resCode = Object.prototype.hasOwnProperty.call(data, 'code')
268
267
  ? Number(data.code)
269
268
  : -1
270
269
  const isSuccess = resCode === 0 || resCode === 200
271
270
  if (!isSuccess) {
272
271
  reportFlag = true
273
272
  errorType = 'dataError'
274
273
  subMsg = '接口请求返回数据异常'
275
274
  }
276
275
  } else {
277
276
  reportFlag = true
278
277
  errorType = 'statusError'
279
278
  subMsg = '接口请求本身异常'
280
279
  }
281
280
  }
282
281
  reportFlag &&
283
282
  draInterfaceCustomReport({
284
283
  subMsg,
285
284
  url,
286
285
  source,
287
286
  requestType,
288
287
  errorType,
289
288
  ...reqData,
290
289
  ...res,
291
290
  })
292
291
  }
292
+ import Taro from '@tarojs/taro'
293
293
  isSupportHybridHttpRequest,
294
294
  draInterfaceCustomReport,
295
295
  draBusinessCustomReport,
296
296
  jsonHeader = 'application/json;charset=utf-8',
297
297
  formDataHeader = 'application/x-www-form-urlencoded',
298
298
  HYBRID: 'httpRequest_hybrid',
299
299
  TARO: 'httpRequest_taro',
300
300
  #requestTimeStamp: number
301
301
  #responseTimeStamp: number
302
302
  #getResTimeStamp: number
303
303
  #reportType: string
304
304
  #callbackFunction: string
305
305
 
306
306
  async request({
307
307
  url,
308
308
  method = 'POST',
309
309
  timeout = 7000,
310
310
  isColorVerify = false,
311
311
  ...otherOptions
312
312
  }): Promise<Taro.request.SuccessCallbackResult<any>> {
313
313
  const { header: otherHeader, ...otherOpts } = otherOptions
314
314
  const header = {
315
315
  'content-type':
316
316
  method === 'POST'
317
317
  ? RequestHeaderContentType.formDataHeader
318
318
  : RequestHeaderContentType.jsonHeader,
319
319
  ...otherHeader,
320
320
  }
321
321
  let getRequestUrl = url
322
322
  let requestTask
323
323
  const data = otherOpts?.data
324
324
  const isGatewayRequest =
325
325
  url === this.api.apiFunc && typeof data === 'object'
326
326
  if (isGatewayRequest) {
327
327
  getRequestUrl = this._handleSpecialGatewayUrl(url)
328
328
  const shouldUseHybridRequest = this._shouldUseHybridRequest(data)
329
329
  if (shouldUseHybridRequest) {
330
330
  requestTask = this._hybridRequest(getRequestUrl, data)
331
331
  } else {
332
332
  otherOpts.data = await this._prepareGatewayReqData(data, isColorVerify)
333
333
  requestTask = this._taroRequest(
334
334
  getRequestUrl,
335
335
  otherOpts,
336
336
  method,
337
337
  timeout,
338
338
  header,
339
339
  )
340
340
  }
341
341
  } else {
342
342
  requestTask = this._taroRequest(
343
343
  getRequestUrl,
344
344
  otherOpts,
345
345
  method,
346
346
  timeout,
347
347
  header,
348
348
  )
349
349
  }
350
350
  const requestTimeoutPromise =
351
351
  new Promise<ServiceInterFace.RequestPromiseRes>((resolve) => {
352
352
  setTimeout(() => {
353
353
  resolve({
354
354
  statusCode: 500,
355
355
  resTimeoutState: true,
356
356
  errMsg: 'request timeout',
357
357
  })
358
358
  }, timeout)
359
359
  })
360
360
  return Promise.race([requestTask, requestTimeoutPromise]).then(
361
361
  (res: any) => {
362
362
  if (res && res.statusCode === 500 && res.resTimeoutState) {
363
363
  if (this.#reportType === HTTP_REQUEST_TYPE.HYBRID) {
364
364
  this._clearFunction(this.#callbackFunction)
365
365
  } else {
366
366
  requestTask.abort && requestTask.abort()
367
367
  }
368
368
  }
369
369
  this._handleReportInterfaceError(url, data, timeout, res)
370
370
  return res
371
371
  },
372
372
  )
373
373
  }
374
374
 
375
375
  _handleSpecialGatewayUrl(url: string): string {
376
376
  if (isPc && window.location.hostname.includes('.jd.hk')) {
377
377
  return this.api.hkApiFunc
378
378
  }
379
379
  if (
380
380
  isJdApp &&
381
381
  window?.shopGlobalSwitch?.dualProtocol &&
382
382
  !window.location.href.includes('jshopx_vconsole')
383
383
  ) {
384
384
  return window?.shopGlobalSwitch?.dualProtocol?.apiTestApp || url
385
385
  }
386
386
  return url
387
387
  }
388
388
 
389
389
  _shouldUseHybridRequest(data: any): boolean {
390
390
  try {
391
391
  const isWhxFunctionId = /^whx\_/.test(data?.functionId)
392
392
  const isGlobalOpenHybirdHttpRequest =
393
393
  window?.shopGlobalSwitch?.openHybirdHttpRequest === 'true'
394
394
  if (
395
395
  !isJdApp ||
396
396
  !isSupportHybridHttpRequest ||
397
397
  !isGlobalOpenHybirdHttpRequest ||
398
398
  isWhxFunctionId ||
399
399
  isJdAndHarmonyDevice
400
400
  ) {
401
401
  return false
402
402
  }
403
403
  const configData = global.getDynamicConfig('hybridHttpSwitch')
404
404
  const { globalOn = false, grayscale = {} } = configData || {}
405
405
  const buildType = process.env.BUILD_TYPE || ''
406
406
  const isInvokeGray = globalOn || grayscale[buildType]
407
407
  console.log(
408
408
  '使用hybrid请求是否命中灰度,isInvokeGray:',
409
409
  isInvokeGray,
410
410
  '获取mpaas配置hybridHttpSwitch原始数据configData',
411
411
  configData,
412
412
  )
413
413
  const hasWindowXWebView = !!window.XWebView
414
414
  return isInvokeGray && hasWindowXWebView
415
415
  } catch (e) {
416
416
  console.log('获取是否使用Hybrid请求出错,e:', e)
417
417
  return false
418
418
  }
419
419
  }
420
420
 
421
421
  _hybridRequest(url: string, data: any): Promise<any> {
422
422
  return new Promise((resolve, reject) => {
423
423
  try {
424
424
  const changeCurrentUrl = url.startsWith('//') ? `https:${url}` : url
425
425
  const { functionId, body, ...otherH5Param } = data
426
426
  const reqParams = {
427
427
  url: isIosDevice ? `${changeCurrentUrl}/` : changeCurrentUrl,
428
428
  functionId: functionId,
429
429
  body: body,
430
430
  headerType: '0',
431
431
  param: {
432
432
  ...otherH5Param,
433
433
  },
434
434
  header: {
435
435
  Referer: window.location.origin,
436
436
  },
437
437
  }
438
438
  const callbackFunction = this._generateCallbackFunction()
439
439
  this.#callbackFunction = callbackFunction
440
440
  this.#requestTimeStamp = Date.now()
441
441
  this.#reportType = HTTP_REQUEST_TYPE.HYBRID
442
442
  window.XWebView.callNative(
443
443
  'ColorQueryPlugin',
444
444
  'colorRequest',
445
445
  JSON.stringify(reqParams),
446
446
  callbackFunction,
447
447
  '1',
448
448
  )
449
449
  window[callbackFunction] = (result) => {
450
450
  this.#responseTimeStamp = Date.now()
451
451
  try {
452
452
  const resultObj =
453
453
  typeof result === 'string' ? JSON.parse(result) : result
454
454
  resolve(resultObj)
455
455
  } catch (error) {
456
456
  const errMsg = 'hybrid网络请求JSON解析失败, error: ' + error
457
457
  draBusinessCustomReport({
458
458
  type: `${HTTP_REQUEST_TYPE.HYBRID}_jsonParseError`,
459
459
  errMsg,
460
460
  result,
461
461
  })
462
462
  reject({ errMsg })
463
463
  }
464
464
  this._clearFunction(callbackFunction)
465
465
  }
466
466
  } catch (error) {
467
467
  reject({
468
468
  errMsg:
469
469
  'hybrid网络请求,App下调用window.XWebView.callNative出错, error: ' +
470
470
  error,
471
471
  })
472
472
  }
473
473
  })
474
474
  }
475
475
 
476
476
  _generateCallbackFunction() {
477
477
  return `hybridHttpRequestCallback_${Date.now()}_${Math.ceil(
478
478
  Math.random() * 100000,
479
479
  )}`
480
480
  }
481
481
 
482
482
  _clearFunction(functionName: string) {
483
483
  try {
484
484
  delete window[functionName]
485
485
  } catch (e) {
486
486
  window[functionName] = undefined
487
487
  }
488
488
  }
489
489
 
490
490
  async _prepareGatewayReqData(
491
491
  data: any,
492
492
  isColorVerify: boolean,
493
493
  ): Promise<any> {
494
494
  const { functionId } = data
495
495
  console.log('获取当前是否需要color加固', isColorVerify, functionId)
496
496
  if (isColorVerify) {
497
497
  const { h5st } = await colorSign.paramsSign(data)
498
498
  h5st && (data.h5st = encodeURI(h5st))
499
499
  console.log(`${functionId}的apiReq_h5st===>:${h5st}`)
500
500
  }
501
501
  const { jsToken } = await colorSign.getFmInfo()
502
502
  console.log(`${functionId}的api jsToken指纹===>:${jsToken}`)
503
503
  jsToken && (data['x-api-eid-token'] = jsToken)
504
504
  return data
505
505
  }
506
506
 
507
507
  _taroRequest(
508
508
  url: string,
509
509
  otherOpts: any,
510
510
  method: string,
511
511
  timeout: number,
512
512
  header: string,
513
513
  ): Promise<any> {
514
514
  const reqParam = {
515
515
  url,
516
516
  method,
517
517
  timeout,
518
518
  header,
519
519
  credentials: 'include',
520
520
  ...otherOpts,
521
521
  }
522
522
  this.#requestTimeStamp = Date.now()
523
523
  this.#reportType = HTTP_REQUEST_TYPE.TARO
524
524
  return Taro.request(reqParam)
525
525
  }
526
526
 
527
527
  _reportRequestTime(url: string, data: any): void {
528
528
  this.#getResTimeStamp = Date.now()
529
529
  if (this.#reportType === HTTP_REQUEST_TYPE.TARO) {
530
530
  this.#responseTimeStamp = this.#getResTimeStamp
531
531
  }
532
532
  draInterfaceCustomReport(
533
533
  {
534
534
  type: `${this.#reportType}_consumeTime`,
535
535
  url,
536
536
  functionId: data?.functionId,
537
537
  requestTimeStamp: this.#requestTimeStamp,
538
538
  responseTimeStamp: this.#responseTimeStamp,
539
539
  errMsg: `使用${this.#reportType}调用接口请求响应耗时`,
540
540
  source: 'remote',
541
541
  },
542
542
  {
543
543
  consumeTime: `${this.#responseTimeStamp - this.#requestTimeStamp}ms`,
544
544
  getResTime: `${this.#getResTimeStamp - this.#requestTimeStamp}ms`,
545
545
  },
546
546
  )
547
547
  }
548
548
 
549
549
  _handleReportInterfaceError(
550
550
  url: string,
551
551
  reqData: any,
552
552
  timeOut: any,
553
553
  res: any,
554
554
  ): void {
555
555
  const source = 'remote'
556
556
  const requestType = this.#reportType
557
557
  let errorType = ''
558
558
  let subMsg = ''
559
559
  let reportFlag = false
560
560
  if (res) {
561
561
  const { statusCode, data, status, resTimeoutState } = res
562
562
  if (statusCode === 500 && resTimeoutState) {
563
563
  reportFlag = true
564
564
  errorType = 'timeout'
565
565
  subMsg = `接口请求超时${timeOut}ms`
566
566
  } else if ((statusCode === 200 || status === '0') && data) {
567
567
  const resCode = Object.prototype.hasOwnProperty.call(data, 'code')
568
568
  ? Number(data.code)
569
569
  : -1
570
570
  const subCode = Object.prototype.hasOwnProperty.call(data, 'subCode')
571
571
  ? Number(data.subCode)
572
572
  : -1
573
573
  const isSuccess =
574
574
  data.success === true ||
575
575
  data.isSuccess ||
576
576
  resCode === 0 ||
577
577
  resCode === 200 ||
578
578
  subCode === 0
579
579
  if (!isSuccess && resCode !== 3) {
580
580
  reportFlag = true
581
581
  errorType = 'dataError'
582
582
  subMsg = '接口请求返回数据异常'
583
583
  }
584
584
  } else {
585
585
  reportFlag = true
586
586
  errorType = 'statusError'
587
587
  subMsg = '接口请求错误,h5请求statusCode非200,或hybrid请求status非0,或未返回data字段'
588
588
  }
589
589
  }
590
590
  reportFlag &&
591
591
  draInterfaceCustomReport({
592
592
  subMsg,
593
593
  url,
594
594
  source,
595
595
  requestType,
596
596
  errorType,
597
597
  functionId: reqData?.functionId,
598
598
  appid: reqData?.appId,
599
599
  client: reqData?.client,
600
600
  clientVersion: reqData?.clientVersion,
601
601
  statusCode: res?.statusCode,
602
602
  status: res?.status,
603
603
  code: res?.data?.code || res?.data?.subCode,
604
604
  errMsg: res?.errMsg || res?.msg || res?.message || res?.data?.echo,
605
605
  originReqDataStr: JSON.stringify(reqData),
606
606
  originResDataStr: JSON.stringify(res),
607
607
  })
608
608
  }