@neteasecloudmusicapienhanced/api 4.32.0 → 4.32.1

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.
Files changed (439) hide show
  1. package/LICENSE +21 -21
  2. package/README.MD +248 -251
  3. package/app.js +18 -18
  4. package/data/china_ip_ranges.txt +4147 -4147
  5. package/data/deviceid.txt +24641 -24641
  6. package/generateConfig.js +24 -24
  7. package/interface.d.ts +1843 -1836
  8. package/main.js +63 -63
  9. package/module/activate_init_profile.js +9 -9
  10. package/module/aidj_content_rcmd.js +28 -28
  11. package/module/album.js +6 -6
  12. package/module/album_detail.js +12 -12
  13. package/module/album_detail_dynamic.js +12 -12
  14. package/module/album_list.js +16 -16
  15. package/module/album_list_style.js +15 -15
  16. package/module/album_new.js +11 -11
  17. package/module/album_newest.js +6 -6
  18. package/module/album_privilege.js +9 -9
  19. package/module/album_songsaleboard.js +19 -19
  20. package/module/album_sub.js +10 -10
  21. package/module/album_sublist.js +11 -11
  22. package/module/api.js +21 -21
  23. package/module/artist_album.js +15 -15
  24. package/module/artist_desc.js +9 -9
  25. package/module/artist_detail.js +10 -10
  26. package/module/artist_detail_dynamic.js +9 -9
  27. package/module/artist_fans.js +11 -11
  28. package/module/artist_follow_count.js +13 -13
  29. package/module/artist_list.js +33 -33
  30. package/module/artist_mv.js +12 -12
  31. package/module/artist_new_mv.js +12 -12
  32. package/module/artist_new_song.js +12 -12
  33. package/module/artist_songs.js +12 -12
  34. package/module/artist_sub.js +11 -11
  35. package/module/artist_sublist.js +11 -11
  36. package/module/artist_top_song.js +8 -8
  37. package/module/artist_video.js +15 -15
  38. package/module/artists.js +6 -6
  39. package/module/audio_match.js +19 -19
  40. package/module/avatar_upload.js +22 -22
  41. package/module/banner.js +16 -16
  42. package/module/batch.js +12 -12
  43. package/module/broadcast_category_region_get.js +11 -11
  44. package/module/broadcast_channel_collect_list.js +12 -12
  45. package/module/broadcast_channel_currentinfo.js +13 -13
  46. package/module/broadcast_channel_list.js +13 -13
  47. package/module/broadcast_sub.js +12 -12
  48. package/module/calendar.js +8 -8
  49. package/module/captcha_sent.js +11 -11
  50. package/module/captcha_verify.js +11 -11
  51. package/module/cellphone_existence_check.js +10 -10
  52. package/module/check_music.js +30 -30
  53. package/module/cloud.js +164 -164
  54. package/module/cloud_import.js +39 -39
  55. package/module/cloud_lyric_get.js +11 -11
  56. package/module/cloud_match.js +13 -13
  57. package/module/cloud_upload_complete.js +72 -72
  58. package/module/cloud_upload_token.js +111 -111
  59. package/module/cloudsearch.js +13 -13
  60. package/module/comment.js +30 -30
  61. package/module/comment_album.js +16 -16
  62. package/module/comment_dj.js +16 -16
  63. package/module/comment_event.js +15 -15
  64. package/module/comment_floor.js +16 -16
  65. package/module/comment_hot.js +18 -18
  66. package/module/comment_hug_list.js +20 -20
  67. package/module/comment_info_list.js +30 -30
  68. package/module/comment_like.js +20 -20
  69. package/module/comment_music.js +16 -16
  70. package/module/comment_mv.js +16 -16
  71. package/module/comment_new.js +37 -37
  72. package/module/comment_playlist.js +16 -16
  73. package/module/{comment_delete.js → comment_report.js} +11 -10
  74. package/module/comment_video.js +16 -16
  75. package/module/countries_code_list.js +6 -6
  76. package/module/creator_authinfo_get.js +6 -6
  77. package/module/daily_signin.js +16 -16
  78. package/module/digitalAlbum_detail.js +13 -13
  79. package/module/digitalAlbum_ordering.js +22 -22
  80. package/module/digitalAlbum_purchased.js +15 -15
  81. package/module/digitalAlbum_sales.js +13 -13
  82. package/module/djRadio_top.js +15 -15
  83. package/module/dj_banner.js +6 -6
  84. package/module/dj_category_excludehot.js +10 -10
  85. package/module/dj_category_recommend.js +10 -10
  86. package/module/dj_catelist.js +6 -6
  87. package/module/dj_detail.js +9 -9
  88. package/module/dj_difm_all_style_channel.js +9 -9
  89. package/module/dj_difm_channel_subscribe.js +9 -9
  90. package/module/dj_difm_channel_unsubscribe.js +9 -9
  91. package/module/dj_difm_playing_tracks_list.js +11 -11
  92. package/module/dj_difm_subscribe_channels_get.js +13 -13
  93. package/module/dj_hot.js +10 -10
  94. package/module/dj_paygift.js +15 -15
  95. package/module/dj_personalize_recommend.js +12 -12
  96. package/module/dj_program.js +12 -12
  97. package/module/dj_program_detail.js +9 -9
  98. package/module/dj_program_toplist.js +10 -10
  99. package/module/dj_program_toplist_hours.js +13 -13
  100. package/module/dj_radio_hot.js +11 -11
  101. package/module/dj_recommend.js +6 -6
  102. package/module/dj_recommend_type.js +32 -32
  103. package/module/dj_sub.js +10 -10
  104. package/module/dj_sublist.js +11 -11
  105. package/module/dj_subscriber.js +12 -12
  106. package/module/dj_today_perfered.js +13 -13
  107. package/module/dj_toplist.js +14 -14
  108. package/module/dj_toplist_hours.js +10 -10
  109. package/module/dj_toplist_newcomer.js +9 -9
  110. package/module/dj_toplist_pay.js +9 -9
  111. package/module/dj_toplist_popular.js +10 -10
  112. package/module/eapi_decrypt.js +27 -27
  113. package/module/event.js +10 -10
  114. package/module/event_del.js +9 -9
  115. package/module/event_forward.js +11 -11
  116. package/module/fanscenter_basicinfo_age_get.js +6 -6
  117. package/module/fanscenter_basicinfo_gender_get.js +10 -10
  118. package/module/fanscenter_basicinfo_province_get.js +10 -10
  119. package/module/fanscenter_overview_get.js +6 -6
  120. package/module/fanscenter_trend_list.js +10 -10
  121. package/module/fm_trash.js +11 -11
  122. package/module/follow.js +11 -11
  123. package/module/get_userids.js +7 -7
  124. package/module/history_recommend_songs.js +11 -11
  125. package/module/history_recommend_songs_detail.js +13 -13
  126. package/module/homepage_block_page.js +8 -8
  127. package/module/homepage_dragon_ball.js +10 -10
  128. package/module/hot_topic.js +10 -10
  129. package/module/hug_comment.js +16 -16
  130. package/module/inner_version.js +16 -16
  131. package/module/like.js +13 -13
  132. package/module/likelist.js +9 -9
  133. package/module/listen_data_realtime_report.js +11 -11
  134. package/module/listen_data_report.js +12 -12
  135. package/module/listen_data_today_song.js +9 -9
  136. package/module/listen_data_total.js +9 -9
  137. package/module/listen_data_year_report.js +9 -9
  138. package/module/listentogether_accept.js +13 -13
  139. package/module/listentogether_end.js +9 -9
  140. package/module/listentogether_heatbeat.js +12 -12
  141. package/module/listentogether_play_command.js +21 -21
  142. package/module/listentogether_room_check.js +9 -9
  143. package/module/listentogether_room_create.js +9 -9
  144. package/module/listentogether_status.js +10 -10
  145. package/module/listentogether_sync_list_command.js +26 -26
  146. package/module/listentogether_sync_playlist_get.js +13 -13
  147. package/module/login.js +41 -41
  148. package/module/login_cellphone.js +40 -40
  149. package/module/login_qr_check.js +29 -29
  150. package/module/login_qr_create.js +30 -30
  151. package/module/login_qr_key.js +19 -19
  152. package/module/login_refresh.js +21 -21
  153. package/module/login_status.js +21 -21
  154. package/module/logout.js +6 -6
  155. package/module/lyric.js +14 -14
  156. package/module/lyric_new.js +17 -17
  157. package/module/mlog_music_rcmd.js +13 -13
  158. package/module/mlog_to_video.js +13 -13
  159. package/module/mlog_url.js +11 -11
  160. package/module/msg_comments.js +17 -17
  161. package/module/msg_forwards.js +11 -11
  162. package/module/msg_notices.js +10 -10
  163. package/module/msg_private.js +11 -11
  164. package/module/msg_private_history.js +12 -12
  165. package/module/msg_recentcontact.js +11 -11
  166. package/module/music_first_listen_info.js +13 -13
  167. package/module/musician_cloudbean.js +7 -7
  168. package/module/musician_cloudbean_obtain.js +14 -14
  169. package/module/musician_data_overview.js +11 -11
  170. package/module/musician_play_trend.js +14 -14
  171. package/module/musician_sign.js +7 -7
  172. package/module/musician_tasks.js +11 -11
  173. package/module/musician_tasks_new.js +11 -11
  174. package/module/musician_vip_tasks.js +11 -11
  175. package/module/mv_all.js +16 -16
  176. package/module/mv_detail.js +9 -9
  177. package/module/mv_detail_info.js +14 -14
  178. package/module/mv_exclusive_rcmd.js +10 -10
  179. package/module/mv_first.js +12 -12
  180. package/module/mv_sub.js +11 -11
  181. package/module/mv_sublist.js +15 -15
  182. package/module/mv_url.js +14 -14
  183. package/module/nickname_check.js +7 -7
  184. package/module/personal_fm.js +6 -6
  185. package/module/personal_fm_mode.js +14 -14
  186. package/module/personalized.js +16 -16
  187. package/module/personalized_djprogram.js +10 -10
  188. package/module/personalized_mv.js +6 -6
  189. package/module/personalized_newsong.js +15 -15
  190. package/module/personalized_privatecontent.js +10 -10
  191. package/module/personalized_privatecontent_list.js +15 -15
  192. package/module/pl_count.js +6 -6
  193. package/module/playlist_category_list.js +11 -11
  194. package/module/playlist_catlist.js +6 -6
  195. package/module/playlist_cover_update.js +32 -32
  196. package/module/playlist_create.js +11 -11
  197. package/module/playlist_delete.js +9 -9
  198. package/module/playlist_desc_update.js +10 -10
  199. package/module/playlist_detail.js +11 -11
  200. package/module/playlist_detail_dynamic.js +11 -11
  201. package/module/playlist_detail_rcmd_get.js +11 -11
  202. package/module/playlist_highquality_tags.js +10 -10
  203. package/module/playlist_hot.js +6 -6
  204. package/module/playlist_import_name_task_create.js +62 -62
  205. package/module/playlist_import_task_status.js +11 -11
  206. package/module/playlist_mylike.js +12 -12
  207. package/module/playlist_name_update.js +10 -10
  208. package/module/playlist_order_update.js +13 -13
  209. package/module/playlist_privacy.js +10 -10
  210. package/module/playlist_subscribe.js +14 -14
  211. package/module/playlist_subscribers.js +11 -11
  212. package/module/playlist_tags_update.js +10 -10
  213. package/module/playlist_track_add.js +16 -16
  214. package/module/playlist_track_all.js +31 -31
  215. package/module/playlist_track_delete.js +20 -20
  216. package/module/playlist_tracks.js +45 -45
  217. package/module/playlist_update.js +13 -13
  218. package/module/playlist_update_playcount.js +9 -9
  219. package/module/playlist_video_recent.js +9 -9
  220. package/module/playmode_intelligence_list.js +13 -13
  221. package/module/playmode_song_vector.js +8 -8
  222. package/module/program_recommend.js +15 -15
  223. package/module/radio_sport_get.js +9 -9
  224. package/module/rebind.js +16 -16
  225. package/module/recent_listen_list.js +7 -7
  226. package/module/recommend_resource.js +10 -10
  227. package/module/recommend_songs.js +13 -11
  228. package/module/recommend_songs_dislike.js +14 -14
  229. package/module/record_recent_album.js +11 -11
  230. package/module/record_recent_dj.js +11 -11
  231. package/module/record_recent_playlist.js +11 -11
  232. package/module/record_recent_song.js +11 -11
  233. package/module/record_recent_video.js +11 -11
  234. package/module/record_recent_voice.js +11 -11
  235. package/module/register_anonimous.js +53 -53
  236. package/module/register_cellphone.js +15 -15
  237. package/module/related_allvideo.js +14 -14
  238. package/module/related_playlist.js +32 -32
  239. package/module/resource_like.js +14 -14
  240. package/module/sati_resource_list.js +11 -11
  241. package/module/sati_resource_list_more.js +13 -13
  242. package/module/sati_resource_sub.js +10 -10
  243. package/module/sati_resource_sub_list.js +7 -7
  244. package/module/sati_tag_list.js +7 -7
  245. package/module/sati_timescene_resources_get.js +13 -13
  246. package/module/scrobble.js +26 -26
  247. package/module/search.js +21 -21
  248. package/module/search_default.js +6 -6
  249. package/module/search_hot.js +9 -9
  250. package/module/search_hot_detail.js +6 -6
  251. package/module/search_match.js +18 -18
  252. package/module/search_multimatch.js +14 -14
  253. package/module/search_suggest.js +14 -14
  254. package/module/search_suggest_pc.js +13 -13
  255. package/module/send_album.js +12 -12
  256. package/module/send_playlist.js +12 -12
  257. package/module/send_song.js +12 -12
  258. package/module/send_text.js +11 -11
  259. package/module/setting.js +7 -7
  260. package/module/share_resource.js +11 -11
  261. package/module/sheet_list.js +9 -9
  262. package/module/sheet_preview.js +8 -8
  263. package/module/sign_happy_info.js +5 -5
  264. package/module/signin_progress.js +13 -13
  265. package/module/simi_artist.js +12 -12
  266. package/module/simi_mv.js +9 -9
  267. package/module/simi_playlist.js +15 -15
  268. package/module/simi_song.js +15 -15
  269. package/module/simi_user.js +11 -11
  270. package/module/song_chorus.js +11 -11
  271. package/module/song_copyright_rcmd.js +9 -0
  272. package/module/song_creators.js +9 -9
  273. package/module/song_detail.js +11 -11
  274. package/module/song_downlist.js +11 -11
  275. package/module/song_download_url.js +10 -10
  276. package/module/song_download_url_v1.js +13 -13
  277. package/module/song_dynamic_cover.js +9 -9
  278. package/module/song_like.js +12 -12
  279. package/module/song_like_check.js +9 -9
  280. package/module/song_lyrics_mark.js +9 -9
  281. package/module/song_lyrics_mark_add.js +12 -12
  282. package/module/song_lyrics_mark_del.js +9 -9
  283. package/module/song_lyrics_mark_user_page.js +14 -14
  284. package/module/song_monthdownlist.js +11 -11
  285. package/module/song_music_detail.js +9 -9
  286. package/module/song_order_update.js +12 -12
  287. package/module/song_purchased.js +14 -14
  288. package/module/song_red_count.js +9 -9
  289. package/module/song_singledownlist.js +11 -11
  290. package/module/song_url.js +26 -26
  291. package/module/song_url_match.js +38 -38
  292. package/module/song_url_ncmget.js +5 -5
  293. package/module/song_url_v1.js +57 -57
  294. package/module/song_url_v1_302.js +53 -53
  295. package/module/song_wiki_summary.js +8 -8
  296. package/module/starpick_comments_summary.js +12 -12
  297. package/module/style_album.js +16 -16
  298. package/module/style_artist.js +16 -16
  299. package/module/style_detail.js +9 -9
  300. package/module/style_list.js +7 -7
  301. package/module/style_playlist.js +16 -16
  302. package/module/style_preference.js +11 -11
  303. package/module/style_song.js +12 -12
  304. package/module/summary_annual.js +12 -12
  305. package/module/threshold_detail_get.js +10 -10
  306. package/module/top_album.js +22 -22
  307. package/module/top_artists.js +11 -11
  308. package/module/top_list.js +20 -20
  309. package/module/top_mv.js +12 -12
  310. package/module/top_playlist.js +22 -22
  311. package/module/top_playlist_highquality.js +16 -16
  312. package/module/top_song.js +16 -16
  313. package/module/topic_detail.js +7 -7
  314. package/module/topic_detail_event_hot.js +7 -7
  315. package/module/topic_sublist.js +11 -11
  316. package/module/toplist.js +6 -6
  317. package/module/toplist_artist.js +12 -12
  318. package/module/toplist_detail.js +6 -6
  319. package/module/toplist_detail_v2.js +6 -6
  320. package/module/ugc_album_get.js +8 -8
  321. package/module/ugc_artist_get.js +8 -8
  322. package/module/ugc_artist_search.js +10 -10
  323. package/module/ugc_detail.js +17 -17
  324. package/module/ugc_mv_get.js +8 -8
  325. package/module/ugc_song_get.js +8 -8
  326. package/module/ugc_user_devote.js +6 -6
  327. package/module/user_account.js +5 -5
  328. package/module/user_audio.js +9 -9
  329. package/module/user_binding.js +9 -9
  330. package/module/user_bindingcellphone.js +15 -15
  331. package/module/user_cloud.js +10 -10
  332. package/module/user_cloud_del.js +9 -9
  333. package/module/user_cloud_detail.js +10 -10
  334. package/module/user_comment_history.js +15 -15
  335. package/module/user_detail.js +15 -15
  336. package/module/user_detail_new.js +20 -20
  337. package/module/user_dj.js +14 -14
  338. package/module/user_event.js +12 -12
  339. package/module/user_follow_mixed.js +23 -23
  340. package/module/user_followeds.js +17 -17
  341. package/module/user_follows.js +15 -15
  342. package/module/user_level.js +7 -7
  343. package/module/user_medal.js +11 -11
  344. package/module/user_mutualfollow_get.js +9 -9
  345. package/module/user_playlist.js +12 -12
  346. package/module/user_playlist_collect.js +14 -14
  347. package/module/user_playlist_create.js +14 -14
  348. package/module/user_record.js +10 -10
  349. package/module/user_replacephone.js +14 -14
  350. package/module/user_social_status.js +11 -11
  351. package/module/user_social_status_edit.js +16 -16
  352. package/module/user_social_status_rcmd.js +5 -5
  353. package/module/user_social_status_support.js +5 -5
  354. package/module/user_subcount.js +6 -6
  355. package/module/user_update.js +15 -15
  356. package/module/verify_getQr.js +39 -39
  357. package/module/verify_qrcodestatus.js +12 -12
  358. package/module/video_category_list.js +15 -15
  359. package/module/video_detail.js +13 -13
  360. package/module/video_detail_info.js +14 -14
  361. package/module/video_group.js +16 -16
  362. package/module/video_group_list.js +11 -11
  363. package/module/video_sub.js +14 -14
  364. package/module/video_timeline_all.js +17 -17
  365. package/module/video_timeline_recommend.js +13 -13
  366. package/module/video_url.js +10 -10
  367. package/module/vip_growthpoint.js +11 -11
  368. package/module/vip_growthpoint_details.js +14 -14
  369. package/module/vip_growthpoint_get.js +13 -13
  370. package/module/vip_info.js +12 -12
  371. package/module/vip_info_v2.js +12 -12
  372. package/module/vip_sign.js +7 -11
  373. package/module/vip_sign_info.js +11 -11
  374. package/module/vip_tasks.js +11 -11
  375. package/module/vip_timemachine.js +17 -17
  376. package/module/voice_delete.js +7 -7
  377. package/module/voice_detail.js +7 -7
  378. package/module/voice_lyric.js +7 -7
  379. package/module/voice_upload.js +200 -200
  380. package/module/voicelist_detail.js +11 -11
  381. package/module/voicelist_list.js +13 -13
  382. package/module/voicelist_list_search.js +14 -14
  383. package/module/voicelist_my_created.js +13 -13
  384. package/module/voicelist_search.js +11 -11
  385. package/module/voicelist_trans.js +15 -15
  386. package/module/weblog.js +10 -10
  387. package/module/yunbei.js +6 -6
  388. package/module/yunbei_expense.js +8 -8
  389. package/module/yunbei_info.js +5 -5
  390. package/module/yunbei_rcmd_song.js +17 -17
  391. package/module/yunbei_rcmd_song_history.js +16 -16
  392. package/module/yunbei_receipt.js +8 -8
  393. package/module/yunbei_sign.js +5 -5
  394. package/module/yunbei_task_finish.js +12 -12
  395. package/module/yunbei_tasks.js +9 -9
  396. package/module/yunbei_tasks_todo.js +9 -9
  397. package/module/yunbei_today.js +5 -5
  398. package/package.json +8 -8
  399. package/plugins/songUpload.js +109 -109
  400. package/plugins/upload.js +35 -35
  401. package/public/api.html +222 -222
  402. package/public/audio_match_demo/afp.js +1626 -1626
  403. package/public/audio_match_demo/afp.wasm.js +5 -5
  404. package/public/audio_match_demo/index.html +367 -367
  405. package/public/audio_match_demo/rec.js +49 -49
  406. package/public/avatar_update.html +326 -326
  407. package/public/cloud.html +578 -578
  408. package/public/docs/_coverpage.md +13 -13
  409. package/public/docs/home.md +5318 -5325
  410. package/public/docs/index.html +129 -47
  411. package/public/docs/logo.svg +6 -6
  412. package/public/docs/netease.png +0 -0
  413. package/public/docs/sw.js +90 -90
  414. package/public/eapi_decrypt.html +264 -264
  415. package/public/home.html +40 -40
  416. package/public/index.html +124 -124
  417. package/public/listen_together_host.html +552 -552
  418. package/public/login.html +219 -219
  419. package/public/playlist_cover_update.html +323 -323
  420. package/public/playlist_import.html +416 -416
  421. package/public/qrlogin-nocookie.html +199 -199
  422. package/public/qrlogin.html +199 -199
  423. package/public/static/2169.png +0 -0
  424. package/public/static/neteaselogo.png +0 -0
  425. package/public/unblock_test.html +153 -153
  426. package/public/voice_upload.html +326 -326
  427. package/server.js +454 -454
  428. package/util/apicache.js +836 -836
  429. package/util/client-sign.js +169 -169
  430. package/util/config.json +20 -20
  431. package/util/crypto.js +153 -153
  432. package/util/fileHelper.js +88 -88
  433. package/util/index.js +233 -233
  434. package/util/logger.js +42 -42
  435. package/util/memory-cache.js +71 -71
  436. package/util/option.js +14 -14
  437. package/util/request.js +367 -367
  438. package/module/comment_add.js +0 -15
  439. package/module/comment_reply.js +0 -13
package/util/request.js CHANGED
@@ -1,367 +1,367 @@
1
- // 预先导入和绑定常用模块及函数
2
- const encrypt = require('./crypto')
3
- const CryptoJS = require('crypto-js')
4
- const { default: axios } = require('axios')
5
- const { PacProxyAgent } = require('pac-proxy-agent')
6
- const http = require('http')
7
- const https = require('https')
8
- const tunnel = require('tunnel')
9
- const fs = require('fs')
10
- const path = require('path')
11
- const tmpPath = require('os').tmpdir()
12
- const {
13
- cookieToJson,
14
- cookieObjToString,
15
- toBoolean,
16
- generateRandomChineseIP,
17
- } = require('./index')
18
- const { URLSearchParams, URL } = require('url')
19
- const { APP_CONF } = require('../util/config.json')
20
-
21
- // 预先读取匿名token并缓存
22
- const anonymous_token = fs.readFileSync(
23
- path.resolve(tmpPath, './anonymous_token'),
24
- 'utf-8',
25
- )
26
-
27
- // 预先绑定常用函数和常量
28
- const floor = Math.floor
29
- const random = Math.random
30
- const now = Date.now
31
- const keys = Object.keys
32
- const stringify = JSON.stringify
33
- const parse = JSON.parse
34
- const characters = 'abcdefghijklmnopqrstuvwxyz'
35
- const charactersLength = characters.length
36
-
37
- // 预先创建HTTP/HTTPS agents并重用
38
- const createHttpAgent = () => new http.Agent({ keepAlive: true })
39
- const createHttpsAgent = () => new https.Agent({ keepAlive: true })
40
-
41
- // 预先计算WNMCID(只计算一次)
42
- const WNMCID = (function () {
43
- let randomString = ''
44
- for (let i = 0; i < 6; i++) {
45
- randomString += characters.charAt(floor(random() * charactersLength))
46
- }
47
- return `${randomString}.${now().toString()}.01.0`
48
- })()
49
-
50
- // 预先定义osMap
51
- const osMap = {
52
- pc: {
53
- os: 'pc',
54
- appver: '3.1.17.204416',
55
- osver: 'Microsoft-Windows-10-Professional-build-19045-64bit',
56
- channel: 'netease',
57
- },
58
- linux: {
59
- os: 'linux',
60
- appver: '1.2.1.0428',
61
- osver: 'Deepin 20.9',
62
- channel: 'netease',
63
- },
64
- android: {
65
- os: 'android',
66
- appver: '8.20.20.231215173437',
67
- osver: '14',
68
- channel: 'xiaomi',
69
- },
70
- iphone: {
71
- os: 'iPhone OS',
72
- appver: '9.0.90',
73
- osver: '16.2',
74
- channel: 'distribution',
75
- },
76
- }
77
-
78
- // 预先定义userAgentMap
79
- const userAgentMap = {
80
- weapi: {
81
- pc: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0',
82
- },
83
- linuxapi: {
84
- linux:
85
- 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36',
86
- },
87
- api: {
88
- pc: 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36 Chrome/91.0.4472.164 NeteaseMusicDesktop/3.0.18.203152',
89
- android:
90
- 'NeteaseMusic/9.1.65.240927161425(9001065);Dalvik/2.1.0 (Linux; U; Android 14; 23013RK75C Build/UKQ1.230804.001)',
91
- iphone: 'NeteaseMusic 9.0.90/5038 (iPhone; iOS 16.2; zh_CN)',
92
- },
93
- }
94
-
95
- // 预先定义常量
96
- const DOMAIN = APP_CONF.domain
97
- const API_DOMAIN = APP_CONF.apiDomain
98
- const ENCRYPT_RESPONSE = APP_CONF.encryptResponse
99
- const SPECIAL_STATUS_CODES = new Set([201, 302, 400, 502, 800, 801, 802, 803])
100
-
101
- // chooseUserAgent函数
102
- const chooseUserAgent = (crypto, uaType = 'pc') => {
103
- return (userAgentMap[crypto] && userAgentMap[crypto][uaType]) || ''
104
- }
105
-
106
- // cookie处理
107
- const processCookieObject = (cookie, uri) => {
108
- const _ntes_nuid = CryptoJS.lib.WordArray.random(32).toString()
109
- const os = osMap[cookie.os] || osMap['pc']
110
-
111
- const processedCookie = {
112
- ...cookie,
113
- __remember_me: 'true',
114
- ntes_kaola_ad: '1',
115
- _ntes_nuid: cookie._ntes_nuid || _ntes_nuid,
116
- _ntes_nnid: cookie._ntes_nnid || `${_ntes_nuid},${now().toString()}`,
117
- WNMCID: cookie.WNMCID || WNMCID,
118
- WEVNSM: cookie.WEVNSM || '1.0.0',
119
- osver: cookie.osver || os.osver,
120
- deviceId: cookie.deviceId || global.deviceId,
121
- os: cookie.os || os.os,
122
- channel: cookie.channel || os.channel,
123
- appver: cookie.appver || os.appver,
124
- }
125
-
126
- if (uri.indexOf('login') === -1) {
127
- processedCookie['NMTID'] = CryptoJS.lib.WordArray.random(16).toString()
128
- }
129
-
130
- if (!processedCookie.MUSIC_U) {
131
- processedCookie.MUSIC_A = processedCookie.MUSIC_A || anonymous_token
132
- }
133
-
134
- return processedCookie
135
- }
136
-
137
- // header cookie生成
138
- const createHeaderCookie = (header) => {
139
- const headerKeys = keys(header)
140
- const cookieParts = new Array(headerKeys.length)
141
-
142
- for (let i = 0, len = headerKeys.length; i < len; i++) {
143
- const key = headerKeys[i]
144
- cookieParts[i] =
145
- encodeURIComponent(key) + '=' + encodeURIComponent(header[key])
146
- }
147
-
148
- return cookieParts.join('; ')
149
- }
150
-
151
- // requestId生成
152
- const generateRequestId = () => {
153
- return `${now()}_${floor(random() * 1000)
154
- .toString()
155
- .padStart(4, '0')}`
156
- }
157
-
158
- const createRequest = (uri, data, options) => {
159
- return new Promise((resolve, reject) => {
160
- // 变量声明和初始化
161
- const headers = options.headers ? { ...options.headers } : {}
162
- const ip = options.realIP || options.ip || ''
163
-
164
- // IP头设置
165
- if (ip) {
166
- headers['X-Real-IP'] = ip
167
- headers['X-Forwarded-For'] = ip
168
- }
169
-
170
- let cookie = options.cookie || {}
171
- if (typeof cookie === 'string') {
172
- cookie = cookieToJson(cookie)
173
- }
174
-
175
- if (typeof cookie === 'object') {
176
- cookie = processCookieObject(cookie, uri)
177
- headers['Cookie'] = cookieObjToString(cookie)
178
- }
179
- let url = ''
180
- let encryptData = ''
181
- let crypto = options.crypto
182
- const csrfToken = cookie['__csrf'] || ''
183
-
184
- // 加密方式选择
185
- if (crypto === '') {
186
- crypto = APP_CONF.encrypt ? 'eapi' : 'api'
187
- }
188
-
189
- const answer = { status: 500, body: {}, cookie: [] }
190
-
191
- data.e_r = toBoolean(
192
- options.e_r !== undefined
193
- ? options.e_r
194
- : data.e_r !== undefined
195
- ? data.e_r
196
- : ENCRYPT_RESPONSE,
197
- )
198
- // 根据加密方式处理
199
- switch (crypto) {
200
- case 'weapi':
201
- headers['Referer'] = options.domain || DOMAIN
202
- headers['User-Agent'] = options.ua || chooseUserAgent('weapi')
203
- data.csrf_token = csrfToken
204
- encryptData = encrypt.weapi(data)
205
- url = (options.domain || DOMAIN) + '/weapi/' + uri.substr(5)
206
- break
207
-
208
- case 'linuxapi':
209
- headers['User-Agent'] =
210
- options.ua || chooseUserAgent('linuxapi', 'linux')
211
- encryptData = encrypt.linuxapi({
212
- method: 'POST',
213
- url: (options.domain || DOMAIN) + uri,
214
- params: data,
215
- })
216
- url = (options.domain || DOMAIN) + '/api/linux/forward'
217
- break
218
-
219
- case 'eapi':
220
- case 'api':
221
- // header创建
222
- const header = {
223
- osver: cookie.osver,
224
- deviceId: cookie.deviceId,
225
- os: cookie.os,
226
- appver: cookie.appver,
227
- versioncode: cookie.versioncode || '140',
228
- mobilename: cookie.mobilename || '',
229
- buildver: cookie.buildver || now().toString().substr(0, 10),
230
- resolution: cookie.resolution || '1920x1080',
231
- __csrf: csrfToken,
232
- channel: cookie.channel,
233
- requestId: generateRequestId(),
234
- ...(options.checkToken
235
- ? { 'X-antiCheatToken': APP_CONF.checkToken }
236
- : {}),
237
- // clientSign: APP_CONF.clientSign,
238
- }
239
-
240
- if (cookie.MUSIC_U) header['MUSIC_U'] = cookie.MUSIC_U
241
- if (cookie.MUSIC_A) header['MUSIC_A'] = cookie.MUSIC_A
242
-
243
- headers['Cookie'] = createHeaderCookie(header)
244
- headers['User-Agent'] = options.ua || chooseUserAgent('api', 'iphone')
245
-
246
- if (crypto === 'eapi') {
247
- // headers['x-aeapi'] = true // 服务器会使用gzip压缩返回值
248
- data.header = header
249
-
250
- encryptData = encrypt.eapi(uri, data)
251
- url = (options.domain || API_DOMAIN) + '/eapi/' + uri.substr(5)
252
- } else if (crypto === 'api') {
253
- url = (options.domain || API_DOMAIN) + uri
254
- encryptData = data
255
- }
256
- break
257
-
258
- default:
259
- console.log('[ERR]', 'Unknown Crypto:', crypto)
260
- break
261
- }
262
- // console.log(url);
263
- // settings创建
264
- let settings = {
265
- method: 'POST',
266
- url: url,
267
- headers: headers,
268
- data: new URLSearchParams(encryptData).toString(),
269
- httpAgent: createHttpAgent(),
270
- httpsAgent: createHttpsAgent(),
271
- }
272
-
273
- // 使用返回值加密
274
- const use_e_r = (crypto === 'eapi' || crypto === 'weapi') && data.e_r
275
- if (use_e_r) {
276
- settings.encoding = null
277
- settings.responseType = 'arraybuffer'
278
- }
279
-
280
- // 代理处理
281
- if (options.proxy) {
282
- if (options.proxy.indexOf('pac') > -1) {
283
- const agent = new PacProxyAgent(options.proxy)
284
- settings.httpAgent = agent
285
- settings.httpsAgent = agent
286
- } else {
287
- try {
288
- const purl = new URL(options.proxy)
289
- if (purl.hostname) {
290
- const isHttps = purl.protocol === 'https:'
291
- const agent = tunnel[isHttps ? 'httpsOverHttp' : 'httpOverHttp']({
292
- proxy: {
293
- host: purl.hostname,
294
- port: purl.port || 80,
295
- proxyAuth:
296
- purl.username && purl.password
297
- ? purl.username + ':' + purl.password
298
- : '',
299
- },
300
- })
301
- settings.httpsAgent = agent
302
- settings.httpAgent = agent
303
- settings.proxy = false
304
- } else {
305
- console.error('代理配置无效,不使用代理')
306
- }
307
- } catch (e) {
308
- console.error('代理URL解析失败:', e.message)
309
- }
310
- }
311
- } else {
312
- settings.proxy = false
313
- }
314
- // console.log(settings.headers);
315
- axios(settings)
316
- .then((res) => {
317
- const body = res.data
318
- answer.cookie = (res.headers['set-cookie'] || []).map((x) =>
319
- x.replace(/\s*Domain=[^(;|$)]+;*/, ''),
320
- )
321
-
322
- try {
323
- if (use_e_r) {
324
- answer.body = encrypt.eapiResDecrypt(
325
- body.toString('hex').toUpperCase(),
326
- headers['x-aeapi'],
327
- )
328
- } else {
329
- answer.body =
330
- typeof body === 'object' ? body : parse(body.toString())
331
- }
332
-
333
- if (answer.body.code) {
334
- answer.body.code = Number(answer.body.code)
335
- }
336
-
337
- answer.status = Number(answer.body.code || res.status)
338
-
339
- // 状态码检查(使用Set提升查找性能)
340
- if (SPECIAL_STATUS_CODES.has(answer.body.code)) {
341
- answer.status = 200
342
- }
343
- } catch (e) {
344
- answer.body = body
345
- answer.status = res.status
346
- }
347
-
348
- answer.status =
349
- answer.status > 100 && answer.status < 600 ? answer.status : 400
350
-
351
- if (answer.status === 200) {
352
- resolve(answer)
353
- } else {
354
- console.log('[ERR]', answer)
355
- reject(answer)
356
- }
357
- })
358
- .catch((err) => {
359
- answer.status = 502
360
- answer.body = { code: 502, msg: err.message || err }
361
- console.log('[ERR]', answer)
362
- reject(answer)
363
- })
364
- })
365
- }
366
-
367
- module.exports = createRequest
1
+ // 预先导入和绑定常用模块及函数
2
+ const encrypt = require('./crypto')
3
+ const CryptoJS = require('crypto-js')
4
+ const { default: axios } = require('axios')
5
+ const { PacProxyAgent } = require('pac-proxy-agent')
6
+ const http = require('http')
7
+ const https = require('https')
8
+ const tunnel = require('tunnel')
9
+ const fs = require('fs')
10
+ const path = require('path')
11
+ const tmpPath = require('os').tmpdir()
12
+ const {
13
+ cookieToJson,
14
+ cookieObjToString,
15
+ toBoolean,
16
+ generateRandomChineseIP,
17
+ } = require('./index')
18
+ const { URLSearchParams, URL } = require('url')
19
+ const { APP_CONF } = require('../util/config.json')
20
+
21
+ // 预先读取匿名token并缓存
22
+ const anonymous_token = fs.readFileSync(
23
+ path.resolve(tmpPath, './anonymous_token'),
24
+ 'utf-8',
25
+ )
26
+
27
+ // 预先绑定常用函数和常量
28
+ const floor = Math.floor
29
+ const random = Math.random
30
+ const now = Date.now
31
+ const keys = Object.keys
32
+ const stringify = JSON.stringify
33
+ const parse = JSON.parse
34
+ const characters = 'abcdefghijklmnopqrstuvwxyz'
35
+ const charactersLength = characters.length
36
+
37
+ // 预先创建HTTP/HTTPS agents并重用
38
+ const createHttpAgent = () => new http.Agent({ keepAlive: true })
39
+ const createHttpsAgent = () => new https.Agent({ keepAlive: true })
40
+
41
+ // 预先计算WNMCID(只计算一次)
42
+ const WNMCID = (function () {
43
+ let randomString = ''
44
+ for (let i = 0; i < 6; i++) {
45
+ randomString += characters.charAt(floor(random() * charactersLength))
46
+ }
47
+ return `${randomString}.${now().toString()}.01.0`
48
+ })()
49
+
50
+ // 预先定义osMap
51
+ const osMap = {
52
+ pc: {
53
+ os: 'pc',
54
+ appver: '3.1.17.204416',
55
+ osver: 'Microsoft-Windows-10-Professional-build-19045-64bit',
56
+ channel: 'netease',
57
+ },
58
+ linux: {
59
+ os: 'linux',
60
+ appver: '1.2.1.0428',
61
+ osver: 'Deepin 20.9',
62
+ channel: 'netease',
63
+ },
64
+ android: {
65
+ os: 'android',
66
+ appver: '8.20.20.231215173437',
67
+ osver: '14',
68
+ channel: 'xiaomi',
69
+ },
70
+ iphone: {
71
+ os: 'iPhone OS',
72
+ appver: '9.0.90',
73
+ osver: '16.2',
74
+ channel: 'distribution',
75
+ },
76
+ }
77
+
78
+ // 预先定义userAgentMap
79
+ const userAgentMap = {
80
+ weapi: {
81
+ pc: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0',
82
+ },
83
+ linuxapi: {
84
+ linux:
85
+ 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36',
86
+ },
87
+ api: {
88
+ pc: 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36 Chrome/91.0.4472.164 NeteaseMusicDesktop/3.0.18.203152',
89
+ android:
90
+ 'NeteaseMusic/9.1.65.240927161425(9001065);Dalvik/2.1.0 (Linux; U; Android 14; 23013RK75C Build/UKQ1.230804.001)',
91
+ iphone: 'NeteaseMusic 9.0.90/5038 (iPhone; iOS 16.2; zh_CN)',
92
+ },
93
+ }
94
+
95
+ // 预先定义常量
96
+ const DOMAIN = APP_CONF.domain
97
+ const API_DOMAIN = APP_CONF.apiDomain
98
+ const ENCRYPT_RESPONSE = APP_CONF.encryptResponse
99
+ const SPECIAL_STATUS_CODES = new Set([201, 302, 400, 502, 800, 801, 802, 803])
100
+
101
+ // chooseUserAgent函数
102
+ const chooseUserAgent = (crypto, uaType = 'pc') => {
103
+ return (userAgentMap[crypto] && userAgentMap[crypto][uaType]) || ''
104
+ }
105
+
106
+ // cookie处理
107
+ const processCookieObject = (cookie, uri) => {
108
+ const _ntes_nuid = CryptoJS.lib.WordArray.random(32).toString()
109
+ const os = osMap[cookie.os] || osMap['pc']
110
+
111
+ const processedCookie = {
112
+ ...cookie,
113
+ __remember_me: 'true',
114
+ ntes_kaola_ad: '1',
115
+ _ntes_nuid: cookie._ntes_nuid || _ntes_nuid,
116
+ _ntes_nnid: cookie._ntes_nnid || `${_ntes_nuid},${now().toString()}`,
117
+ WNMCID: cookie.WNMCID || WNMCID,
118
+ WEVNSM: cookie.WEVNSM || '1.0.0',
119
+ osver: cookie.osver || os.osver,
120
+ deviceId: cookie.deviceId || global.deviceId,
121
+ os: cookie.os || os.os,
122
+ channel: cookie.channel || os.channel,
123
+ appver: cookie.appver || os.appver,
124
+ }
125
+
126
+ if (uri.indexOf('login') === -1) {
127
+ processedCookie['NMTID'] = CryptoJS.lib.WordArray.random(16).toString()
128
+ }
129
+
130
+ if (!processedCookie.MUSIC_U) {
131
+ processedCookie.MUSIC_A = processedCookie.MUSIC_A || anonymous_token
132
+ }
133
+
134
+ return processedCookie
135
+ }
136
+
137
+ // header cookie生成
138
+ const createHeaderCookie = (header) => {
139
+ const headerKeys = keys(header)
140
+ const cookieParts = new Array(headerKeys.length)
141
+
142
+ for (let i = 0, len = headerKeys.length; i < len; i++) {
143
+ const key = headerKeys[i]
144
+ cookieParts[i] =
145
+ encodeURIComponent(key) + '=' + encodeURIComponent(header[key])
146
+ }
147
+
148
+ return cookieParts.join('; ')
149
+ }
150
+
151
+ // requestId生成
152
+ const generateRequestId = () => {
153
+ return `${now()}_${floor(random() * 1000)
154
+ .toString()
155
+ .padStart(4, '0')}`
156
+ }
157
+
158
+ const createRequest = (uri, data, options) => {
159
+ return new Promise((resolve, reject) => {
160
+ // 变量声明和初始化
161
+ const headers = options.headers ? { ...options.headers } : {}
162
+ const ip = options.realIP || options.ip || ''
163
+
164
+ // IP头设置
165
+ if (ip) {
166
+ headers['X-Real-IP'] = ip
167
+ headers['X-Forwarded-For'] = ip
168
+ }
169
+
170
+ let cookie = options.cookie || {}
171
+ if (typeof cookie === 'string') {
172
+ cookie = cookieToJson(cookie)
173
+ }
174
+
175
+ if (typeof cookie === 'object') {
176
+ cookie = processCookieObject(cookie, uri)
177
+ headers['Cookie'] = cookieObjToString(cookie)
178
+ }
179
+ let url = ''
180
+ let encryptData = ''
181
+ let crypto = options.crypto
182
+ const csrfToken = cookie['__csrf'] || ''
183
+
184
+ // 加密方式选择
185
+ if (crypto === '') {
186
+ crypto = APP_CONF.encrypt ? 'eapi' : 'api'
187
+ }
188
+
189
+ const answer = { status: 500, body: {}, cookie: [] }
190
+
191
+ data.e_r = toBoolean(
192
+ options.e_r !== undefined
193
+ ? options.e_r
194
+ : data.e_r !== undefined
195
+ ? data.e_r
196
+ : ENCRYPT_RESPONSE,
197
+ )
198
+ // 根据加密方式处理
199
+ switch (crypto) {
200
+ case 'weapi':
201
+ headers['Referer'] = options.domain || DOMAIN
202
+ headers['User-Agent'] = options.ua || chooseUserAgent('weapi')
203
+ data.csrf_token = csrfToken
204
+ encryptData = encrypt.weapi(data)
205
+ url = (options.domain || DOMAIN) + '/weapi/' + uri.substr(5)
206
+ break
207
+
208
+ case 'linuxapi':
209
+ headers['User-Agent'] =
210
+ options.ua || chooseUserAgent('linuxapi', 'linux')
211
+ encryptData = encrypt.linuxapi({
212
+ method: 'POST',
213
+ url: (options.domain || DOMAIN) + uri,
214
+ params: data,
215
+ })
216
+ url = (options.domain || DOMAIN) + '/api/linux/forward'
217
+ break
218
+
219
+ case 'eapi':
220
+ case 'api':
221
+ // header创建
222
+ const header = {
223
+ osver: cookie.osver,
224
+ deviceId: cookie.deviceId,
225
+ os: cookie.os,
226
+ appver: cookie.appver,
227
+ versioncode: cookie.versioncode || '140',
228
+ mobilename: cookie.mobilename || '',
229
+ buildver: cookie.buildver || now().toString().substr(0, 10),
230
+ resolution: cookie.resolution || '1920x1080',
231
+ __csrf: csrfToken,
232
+ channel: cookie.channel,
233
+ requestId: generateRequestId(),
234
+ ...(options.checkToken
235
+ ? { 'X-antiCheatToken': APP_CONF.checkToken }
236
+ : {}),
237
+ // clientSign: APP_CONF.clientSign,
238
+ }
239
+
240
+ if (cookie.MUSIC_U) header['MUSIC_U'] = cookie.MUSIC_U
241
+ if (cookie.MUSIC_A) header['MUSIC_A'] = cookie.MUSIC_A
242
+
243
+ headers['Cookie'] = createHeaderCookie(header)
244
+ headers['User-Agent'] = options.ua || chooseUserAgent('api', 'iphone')
245
+
246
+ if (crypto === 'eapi') {
247
+ // headers['x-aeapi'] = true // 服务器会使用gzip压缩返回值
248
+ data.header = header
249
+
250
+ encryptData = encrypt.eapi(uri, data)
251
+ url = (options.domain || API_DOMAIN) + '/eapi/' + uri.substr(5)
252
+ } else if (crypto === 'api') {
253
+ url = (options.domain || API_DOMAIN) + uri
254
+ encryptData = data
255
+ }
256
+ break
257
+
258
+ default:
259
+ console.log('[ERR]', 'Unknown Crypto:', crypto)
260
+ break
261
+ }
262
+ // console.log(url);
263
+ // settings创建
264
+ let settings = {
265
+ method: 'POST',
266
+ url: url,
267
+ headers: headers,
268
+ data: new URLSearchParams(encryptData).toString(),
269
+ httpAgent: createHttpAgent(),
270
+ httpsAgent: createHttpsAgent(),
271
+ }
272
+
273
+ // 使用返回值加密
274
+ const use_e_r = (crypto === 'eapi' || crypto === 'weapi') && data.e_r
275
+ if (use_e_r) {
276
+ settings.encoding = null
277
+ settings.responseType = 'arraybuffer'
278
+ }
279
+
280
+ // 代理处理
281
+ if (options.proxy) {
282
+ if (options.proxy.indexOf('pac') > -1) {
283
+ const agent = new PacProxyAgent(options.proxy)
284
+ settings.httpAgent = agent
285
+ settings.httpsAgent = agent
286
+ } else {
287
+ try {
288
+ const purl = new URL(options.proxy)
289
+ if (purl.hostname) {
290
+ const isHttps = purl.protocol === 'https:'
291
+ const agent = tunnel[isHttps ? 'httpsOverHttp' : 'httpOverHttp']({
292
+ proxy: {
293
+ host: purl.hostname,
294
+ port: purl.port || 80,
295
+ proxyAuth:
296
+ purl.username && purl.password
297
+ ? purl.username + ':' + purl.password
298
+ : '',
299
+ },
300
+ })
301
+ settings.httpsAgent = agent
302
+ settings.httpAgent = agent
303
+ settings.proxy = false
304
+ } else {
305
+ console.error('代理配置无效,不使用代理')
306
+ }
307
+ } catch (e) {
308
+ console.error('代理URL解析失败:', e.message)
309
+ }
310
+ }
311
+ } else {
312
+ settings.proxy = false
313
+ }
314
+ // console.log(settings.headers);
315
+ axios(settings)
316
+ .then((res) => {
317
+ const body = res.data
318
+ answer.cookie = (res.headers['set-cookie'] || []).map((x) =>
319
+ x.replace(/\s*Domain=[^(;|$)]+;*/, ''),
320
+ )
321
+
322
+ try {
323
+ if (use_e_r) {
324
+ answer.body = encrypt.eapiResDecrypt(
325
+ body.toString('hex').toUpperCase(),
326
+ headers['x-aeapi'],
327
+ )
328
+ } else {
329
+ answer.body =
330
+ typeof body === 'object' ? body : parse(body.toString())
331
+ }
332
+
333
+ if (answer.body.code) {
334
+ answer.body.code = Number(answer.body.code)
335
+ }
336
+
337
+ answer.status = Number(answer.body.code || res.status)
338
+
339
+ // 状态码检查(使用Set提升查找性能)
340
+ if (SPECIAL_STATUS_CODES.has(answer.body.code)) {
341
+ answer.status = 200
342
+ }
343
+ } catch (e) {
344
+ answer.body = body
345
+ answer.status = res.status
346
+ }
347
+
348
+ answer.status =
349
+ answer.status > 100 && answer.status < 600 ? answer.status : 400
350
+
351
+ if (answer.status === 200) {
352
+ resolve(answer)
353
+ } else {
354
+ console.log('[ERR]', answer)
355
+ reject(answer)
356
+ }
357
+ })
358
+ .catch((err) => {
359
+ answer.status = 502
360
+ answer.body = { code: 502, msg: err.message || err }
361
+ console.log('[ERR]', answer)
362
+ reject(answer)
363
+ })
364
+ })
365
+ }
366
+
367
+ module.exports = createRequest