rpc-client.ts 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import Taro from '@tarojs/taro'
  2. import type { Hono } from 'hono'
  3. import { hc } from 'hono/client'
  4. import ResponsePolyfill from './response-polyfill'
  5. // API配置
  6. const API_BASE_URL = process.env.TARO_APP_API_BASE_URL || 'http://localhost:3000'
  7. // 完整的API地址
  8. // const BASE_URL = `${API_BASE_URL}/api/${API_VERSION}`
  9. // 创建自定义fetch函数,适配Taro.request
  10. const taroFetch: any = async (input, init) => {
  11. const url = typeof input === 'string' ? input : input.url
  12. const method = init.method || 'GET'
  13. const requestHeaders: Record<string, string> = init.headers;
  14. const keyOfContentType = Object.keys(requestHeaders).find(item => item.toLowerCase() === 'content-type')
  15. if (!keyOfContentType) {
  16. requestHeaders['content-type'] = 'application/json'
  17. }
  18. // 构建Taro请求选项
  19. const options: Taro.request.Option = {
  20. url,
  21. method: method as any,
  22. data: init.body,
  23. header: requestHeaders
  24. }
  25. // 添加token
  26. const token = Taro.getStorageSync('mini_token')
  27. if (token) {
  28. options.header = {
  29. ...options.header,
  30. 'Authorization': `Bearer ${token}`
  31. }
  32. }
  33. try {
  34. // const response = await Taro.request(options)
  35. console.log('options', options)
  36. const response = await Taro.request(options)
  37. const responseHeaders = response.header;
  38. // if (response.header) {
  39. // for (const [key, value] of Object.entries(response.header)) {
  40. // responseHeaders.set(key, value);
  41. // }
  42. // }
  43. // 处理204 No Content响应,不设置body
  44. const body = response.statusCode === 204
  45. ? null
  46. : responseHeaders['content-type']!.includes('application/json')
  47. ? JSON.stringify(response.data)
  48. : response.data;
  49. return new ResponsePolyfill(
  50. body,
  51. {
  52. status: response.statusCode,
  53. statusText: response.errMsg || 'OK',
  54. headers: responseHeaders
  55. }
  56. )
  57. } catch (error) {
  58. console.error('API Error:', error)
  59. Taro.showToast({
  60. title: error.message || '网络错误',
  61. icon: 'none'
  62. })
  63. throw error
  64. }
  65. }
  66. // 创建Hono RPC客户端
  67. export const rpcClient = <T extends Hono>() => {
  68. return hc<T>(`${API_BASE_URL}`, {
  69. fetch: taroFetch
  70. })
  71. }