hc.ts 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. import axios, { isAxiosError } from 'axios';
  2. import { hc } from 'hono/client'
  3. import type { Hono } from 'hono'
  4. // 创建 axios 适配器
  5. const axiosFetch = async (url: RequestInfo | URL, init?: RequestInit) => {
  6. const requestHeaders: Record<string, string> = {};
  7. if (init?.headers instanceof Headers) {
  8. init.headers.forEach((value, key) => {
  9. requestHeaders[key] = value;
  10. })
  11. }
  12. // 处理URL中的多余斜杠
  13. let requestUrl = url.toString()
  14. // 替换连续的斜杠为单个斜杠,但保留协议后的双斜杠
  15. requestUrl = requestUrl.replace(/([^:])\/\/+/g, '$1/')
  16. // 处理路径末尾的斜杠和查询参数前的斜杠
  17. requestUrl = requestUrl.replace(/\/\?/g, '?')
  18. const response = await axios.request({
  19. url: requestUrl,
  20. method: init?.method || 'GET',
  21. headers: requestHeaders,
  22. data: init?.body,
  23. }).catch((error) => {
  24. console.log('axiosFetch error', error)
  25. if (isAxiosError(error)) {
  26. return {
  27. status: error.response?.status,
  28. statusText: error.response?.statusText,
  29. data: error.response?.data,
  30. headers: error.response?.headers
  31. }
  32. }
  33. throw error;
  34. })
  35. const responseHeaders = new Headers();
  36. if (response.headers) {
  37. for (const [key, value] of Object.entries(response.headers)) {
  38. responseHeaders.set(key, value);
  39. }
  40. }
  41. // 处理204 No Content响应,不设置body
  42. const body = response.status === 204
  43. ? null
  44. : responseHeaders.get('content-type')?.includes('application/json')
  45. ? JSON.stringify(response.data)
  46. : response.data;
  47. return new Response(
  48. body,
  49. {
  50. status: response.status,
  51. statusText: response.statusText,
  52. headers: responseHeaders
  53. }
  54. )
  55. }
  56. // 创建Hono RPC客户端
  57. export const rpcClient = <T extends Hono<any, any, any>>(aptBaseUrl: string): ReturnType<typeof hc<T>> => {
  58. return hc<T>(aptBaseUrl, {
  59. fetch: axiosFetch
  60. })
  61. }