@conecli/cone-render 0.9.1-shop2.31 → 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 || data?.success
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
  code: res?.data?.code,
290
289
  body: reqData?.body,
291
290
  appid: reqData?.appId,
292
291
  t: reqData?.t,
293
292
  client: reqData?.client,
294
293
  clientVersion: reqData?.clientVersion,
295
294
  ...res,
296
295
  })
297
296
  }
297
+ import Taro from '@tarojs/taro'
298
298
  isSupportHybridHttpRequest,
299
299
  draInterfaceCustomReport,
300
300
  draBusinessCustomReport,
301
301
  jsonHeader = 'application/json;charset=utf-8',
302
302
  formDataHeader = 'application/x-www-form-urlencoded',
303
303
  HYBRID: 'httpRequest_hybrid',
304
304
  TARO: 'httpRequest_taro',
305
305
  #requestTimeStamp: number
306
306
  #responseTimeStamp: number
307
307
  #getResTimeStamp: number
308
308
  #reportType: string
309
309
  #callbackFunction: string
310
310
 
311
311
  async request({
312
312
  url,
313
313
  method = 'POST',
314
314
  timeout = 7000,
315
315
  isColorVerify = false,
316
316
  ...otherOptions
317
317
  }): Promise<Taro.request.SuccessCallbackResult<any>> {
318
318
  const { header: otherHeader, ...otherOpts } = otherOptions
319
319
  const header = {
320
320
  'content-type':
321
321
  method === 'POST'
322
322
  ? RequestHeaderContentType.formDataHeader
323
323
  : RequestHeaderContentType.jsonHeader,
324
324
  ...otherHeader,
325
325
  }
326
326
  let getRequestUrl = url
327
327
  let requestTask
328
328
  const data = otherOpts?.data
329
329
  const isGatewayRequest =
330
330
  url === this.api.apiFunc && typeof data === 'object'
331
331
  if (isGatewayRequest) {
332
332
  getRequestUrl = this._handleSpecialGatewayUrl(url)
333
333
  const shouldUseHybridRequest = this._shouldUseHybridRequest(data)
334
334
  if (shouldUseHybridRequest) {
335
335
  requestTask = this._hybridRequest(getRequestUrl, data)
336
336
  } else {
337
337
  otherOpts.data = await this._prepareGatewayReqData(data, isColorVerify)
338
338
  requestTask = this._taroRequest(
339
339
  getRequestUrl,
340
340
  otherOpts,
341
341
  method,
342
342
  timeout,
343
343
  header,
344
344
  )
345
345
  }
346
346
  } else {
347
347
  requestTask = this._taroRequest(
348
348
  getRequestUrl,
349
349
  otherOpts,
350
350
  method,
351
351
  timeout,
352
352
  header,
353
353
  )
354
354
  }
355
355
  const requestTimeoutPromise =
356
356
  new Promise<ServiceInterFace.RequestPromiseRes>((resolve) => {
357
357
  setTimeout(() => {
358
358
  resolve({
359
359
  statusCode: 500,
360
360
  resTimeoutState: true,
361
361
  errMsg: 'request timeout',
362
362
  })
363
363
  }, timeout)
364
364
  })
365
365
  return Promise.race([requestTask, requestTimeoutPromise]).then(
366
366
  (res: any) => {
367
367
  if (res && res.statusCode === 500 && res.resTimeoutState) {
368
368
  if (this.#reportType === HTTP_REQUEST_TYPE.HYBRID) {
369
369
  this._clearFunction(this.#callbackFunction)
370
370
  } else {
371
371
  requestTask.abort && requestTask.abort()
372
372
  }
373
373
  }
374
374
  this._handleReportInterfaceError(url, data, timeout, res)
375
375
  return res
376
376
  },
377
377
  )
378
378
  }
379
379
 
380
380
  _handleSpecialGatewayUrl(url: string): string {
381
381
  if (isPc && window.location.hostname.includes('.jd.hk')) {
382
382
  return this.api.hkApiFunc
383
383
  }
384
384
  if (
385
385
  isJdApp &&
386
386
  window?.shopGlobalSwitch?.dualProtocol &&
387
387
  !window.location.href.includes('jshopx_vconsole')
388
388
  ) {
389
389
  return window?.shopGlobalSwitch?.dualProtocol?.apiTestApp || url
390
390
  }
391
391
  return url
392
392
  }
393
393
 
394
394
  _shouldUseHybridRequest(data: any): boolean {
395
395
  try {
396
396
  const isWhxFunctionId = /^whx\_/.test(data?.functionId)
397
397
  const isGlobalOpenHybirdHttpRequest =
398
398
  window?.shopGlobalSwitch?.openHybirdHttpRequest === 'true'
399
399
  if (
400
400
  !isJdApp ||
401
401
  !isSupportHybridHttpRequest ||
402
402
  !isGlobalOpenHybirdHttpRequest ||
403
403
  isWhxFunctionId ||
404
404
  isJdAndHarmonyDevice
405
405
  ) {
406
406
  return false
407
407
  }
408
408
  const configData = global.getDynamicConfig('hybridHttpSwitch')
409
409
  const { globalOn = false, grayscale = {} } = configData || {}
410
410
  const buildType = process.env.BUILD_TYPE || ''
411
411
  const isInvokeGray = globalOn || grayscale[buildType]
412
412
  console.log(
413
413
  '使用hybrid请求是否命中灰度,isInvokeGray:',
414
414
  isInvokeGray,
415
415
  '获取mpaas配置hybridHttpSwitch原始数据configData',
416
416
  configData,
417
417
  )
418
418
  const hasWindowXWebView = !!window.XWebView
419
419
  return isInvokeGray && hasWindowXWebView
420
420
  } catch (e) {
421
421
  console.log('获取是否使用Hybrid请求出错,e:', e)
422
422
  return false
423
423
  }
424
424
  }
425
425
 
426
426
  _hybridRequest(url: string, data: any): Promise<any> {
427
427
  return new Promise((resolve, reject) => {
428
428
  try {
429
429
  const changeCurrentUrl = url.startsWith('//') ? `https:${url}` : url
430
430
  const { functionId, body, ...otherH5Param } = data
431
431
  const reqParams = {
432
432
  url: isIosDevice ? `${changeCurrentUrl}/` : changeCurrentUrl,
433
433
  functionId: functionId,
434
434
  body: body,
435
435
  headerType: '0',
436
436
  param: {
437
437
  ...otherH5Param,
438
438
  },
439
439
  header: {
440
440
  Referer: window.location.origin,
441
441
  },
442
442
  }
443
443
  const callbackFunction = this._generateCallbackFunction()
444
444
  this.#callbackFunction = callbackFunction
445
445
  this.#requestTimeStamp = Date.now()
446
446
  this.#reportType = HTTP_REQUEST_TYPE.HYBRID
447
447
  window.XWebView.callNative(
448
448
  'ColorQueryPlugin',
449
449
  'colorRequest',
450
450
  JSON.stringify(reqParams),
451
451
  callbackFunction,
452
452
  '1',
453
453
  )
454
454
  window[callbackFunction] = (result) => {
455
455
  this.#responseTimeStamp = Date.now()
456
456
  try {
457
457
  const resultObj =
458
458
  typeof result === 'string' ? JSON.parse(result) : result
459
459
  resolve(resultObj)
460
460
  } catch (error) {
461
461
  const errMsg = 'hybrid网络请求JSON解析失败, error: ' + error
462
462
  draBusinessCustomReport({
463
463
  type: `${HTTP_REQUEST_TYPE.HYBRID}_jsonParseError`,
464
464
  errMsg,
465
465
  result,
466
466
  })
467
467
  reject({ errMsg })
468
468
  }
469
469
  this._clearFunction(callbackFunction)
470
470
  }
471
471
  } catch (error) {
472
472
  reject({
473
473
  errMsg:
474
474
  'hybrid网络请求,App下调用window.XWebView.callNative出错, error: ' +
475
475
  error,
476
476
  })
477
477
  }
478
478
  })
479
479
  }
480
480
 
481
481
  _generateCallbackFunction() {
482
482
  return `hybridHttpRequestCallback_${Date.now()}_${Math.ceil(
483
483
  Math.random() * 100000,
484
484
  )}`
485
485
  }
486
486
 
487
487
  _clearFunction(functionName: string) {
488
488
  try {
489
489
  delete window[functionName]
490
490
  } catch (e) {
491
491
  window[functionName] = undefined
492
492
  }
493
493
  }
494
494
 
495
495
  async _prepareGatewayReqData(
496
496
  data: any,
497
497
  isColorVerify: boolean,
498
498
  ): Promise<any> {
499
499
  const { functionId } = data
500
500
  console.log('获取当前是否需要color加固', isColorVerify, functionId)
501
501
  if (isColorVerify) {
502
502
  const { h5st } = await colorSign.paramsSign(data)
503
503
  h5st && (data.h5st = encodeURI(h5st))
504
504
  console.log(`${functionId}的apiReq_h5st===>:${h5st}`)
505
505
  }
506
506
  const { jsToken } = await colorSign.getFmInfo()
507
507
  console.log(`${functionId}的api jsToken指纹===>:${jsToken}`)
508
508
  jsToken && (data['x-api-eid-token'] = jsToken)
509
509
  return data
510
510
  }
511
511
 
512
512
  _taroRequest(
513
513
  url: string,
514
514
  otherOpts: any,
515
515
  method: string,
516
516
  timeout: number,
517
517
  header: string,
518
518
  ): Promise<any> {
519
519
  const reqParam = {
520
520
  url,
521
521
  method,
522
522
  timeout,
523
523
  header,
524
524
  credentials: 'include',
525
525
  ...otherOpts,
526
526
  }
527
527
  this.#requestTimeStamp = Date.now()
528
528
  this.#reportType = HTTP_REQUEST_TYPE.TARO
529
529
  return Taro.request(reqParam)
530
530
  }
531
531
 
532
532
  _reportRequestTime(url: string, data: any): void {
533
533
  this.#getResTimeStamp = Date.now()
534
534
  if (this.#reportType === HTTP_REQUEST_TYPE.TARO) {
535
535
  this.#responseTimeStamp = this.#getResTimeStamp
536
536
  }
537
537
  draInterfaceCustomReport(
538
538
  {
539
539
  type: `${this.#reportType}_consumeTime`,
540
540
  url,
541
541
  functionId: data?.functionId,
542
542
  requestTimeStamp: this.#requestTimeStamp,
543
543
  responseTimeStamp: this.#responseTimeStamp,
544
544
  errMsg: `使用${this.#reportType}调用接口请求响应耗时`,
545
545
  source: 'remote',
546
546
  },
547
547
  {
548
548
  consumeTime: `${this.#responseTimeStamp - this.#requestTimeStamp}ms`,
549
549
  getResTime: `${this.#getResTimeStamp - this.#requestTimeStamp}ms`,
550
550
  },
551
551
  )
552
552
  }
553
553
 
554
554
  _handleReportInterfaceError(
555
555
  url: string,
556
556
  reqData: any,
557
557
  timeOut: any,
558
558
  res: any,
559
559
  ): void {
560
560
  const source = 'remote'
561
561
  const requestType = this.#reportType
562
562
  let errorType = ''
563
563
  let subMsg = ''
564
564
  let reportFlag = false
565
565
  if (res) {
566
566
  const { statusCode, data, status, resTimeoutState } = res
567
567
  if (statusCode === 500 && resTimeoutState) {
568
568
  reportFlag = true
569
569
  errorType = 'timeout'
570
570
  subMsg = `接口请求超时${timeOut}ms`
571
571
  } else if ((statusCode === 200 || status === '0') && data) {
572
572
  const resCode = Object.prototype.hasOwnProperty.call(data, 'code')
573
573
  ? Number(data.code)
574
574
  : -1
575
575
  const subCode = Object.prototype.hasOwnProperty.call(data, 'subCode')
576
576
  ? Number(data.subCode)
577
577
  : -1
578
578
  const isSuccess =
579
579
  data.success === true ||
580
580
  data.isSuccess ||
581
581
  resCode === 0 ||
582
582
  resCode === 200 ||
583
583
  subCode === 0
584
584
  if (!isSuccess && resCode !== 3) {
585
585
  reportFlag = true
586
586
  errorType = 'dataError'
587
587
  subMsg = '接口请求返回数据异常'
588
588
  }
589
589
  } else {
590
590
  reportFlag = true
591
591
  errorType = 'statusError'
592
592
  subMsg = '接口请求错误,h5请求statusCode非200,或hybrid请求status非0,或未返回data字段'
593
593
  }
594
594
  }
595
595
  reportFlag &&
596
596
  draInterfaceCustomReport({
597
597
  subMsg,
598
598
  url,
599
599
  source,
600
600
  requestType,
601
601
  errorType,
602
602
  functionId: reqData?.functionId,
603
603
  appid: reqData?.appId,
604
604
  client: reqData?.client,
605
605
  clientVersion: reqData?.clientVersion,
606
606
  statusCode: res?.statusCode,
607
607
  status: res?.status,
608
608
  code: res?.data?.code || res?.data?.subCode,
609
609
  errMsg: res?.errMsg || res?.msg || res?.message || res?.data?.echo,
610
610
  originReqDataStr: JSON.stringify(reqData),
611
611
  originResDataStr: JSON.stringify(res),
612
612
  })
613
613
  }