返回 AiToEarn
requestNet.ts
根目录 / project / aitoearn-electron / electron / plat / requestNet.ts
1 import { net, session, Session } from 'electron';
2 import FormData from 'form-data';
3 import { ipv4Regular } from '../../commont/regular';
4 import { parseProxyString } from '../../commont/utils';
5 import { ProxyInfo } from '@@/utils.type';
6
7 export interface IRequestNetResult<T> {
8 status: number;
9 headers: Record<any, any>;
10 data: T;
11 }
12
13 export interface IRequestNetParams {
14 headers?: Record<string, string | string[]>;
15 url?: string;
16 body?: any;
17 method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
18 // 是否请求文件
19 isReqFile?: boolean;
20 // body是否为文件
21 isFile?: boolean;
22 formData?: FormData;
23 // 代理配置,例如 "http=proxy1.com:8080"
24 proxy?: string;
25 }
26
27 const requestNet = <T = any>({
28 headers,
29 body,
30 method,
31 url,
32 isFile,
33 formData,
34 isReqFile,
35 proxy,
36 }: IRequestNetParams): Promise<IRequestNetResult<T>> => {
37 let customSession: Session;
38 let proxyInfo: ProxyInfo | false;
39 return new Promise(async (resolve, reject) => {
40 try {
41 // 如果传入了代理配置,动态设置代理
42 if (proxy) {
43 // 解析代理信息
44 proxyInfo = parseProxyString(proxy);
45 if (proxyInfo === false || !ipv4Regular.test(proxyInfo.ipAndPort))
46 throw new Error('代理地址不合法');
47 customSession = session.fromPartition(
48 `persist:proxy-session-${Date.now()}`,
49 );
50 const proxyUrl = `${proxyInfo.protocol}://${proxyInfo.ipAndPort}`;
51 const proxyRules = `http=${proxyUrl};https=${proxyUrl}`;
52 console.log(proxyRules);
53 await customSession.setProxy({
54 proxyRules,
55 });
56
57 headers = {
58 ...(headers ? headers : {}),
59 ...(proxy
60 ? {
61 'x-forwarded-for': proxyInfo.ipAndPort,
62 }
63 : {}),
64 };
65 }
66
67 if (formData) {
68 headers = {
69 ...(headers ? headers : {}),
70 ...formData.getHeaders(),
71 };
72 }
73
74 const req = net.request({
75 method: method || 'GET',
76 url,
77 // 如果有代理,使用自定义 session
78 session: proxy ? customSession! : undefined,
79 headers,
80 });
81
82 // 设置请求头
83 if (headers) {
84 Object.entries(headers).forEach(([key, value]) => {
85 req.setHeader(key, value as string);
86 });
87 }
88
89 // 处理响应
90 req.on('response', (response) => {
91 const chunks: Buffer<ArrayBufferLike>[] = [];
92 let data = '';
93 response.on('data', (chunk) => {
94 if (isReqFile) {
95 chunks.push(chunk);
96 } else {
97 data += chunk;
98 }
99 });
100
101 response.on('end', () => {
102 let parsedData: T;
103 if (isReqFile) {
104 const buffer = Buffer.concat(chunks);
105 parsedData = buffer as any;
106 } else {
107 try {
108 parsedData = JSON.parse(data);
109 } catch (e) {
110 parsedData = data as T;
111 }
112 }
113 resolve({
114 status: response.statusCode,
115 headers: response.headers,
116 data: parsedData,
117 });
118 });
119 });
120
121 if (proxyInfo && typeof proxyInfo === 'object') {
122 req.on('login', (authInfo, callback) => {
123 callback(
124 (proxyInfo as ProxyInfo).username,
125 (proxyInfo as ProxyInfo).password,
126 );
127 });
128 }
129
130 // 错误处理
131 req.on('error', (error) => {
132 console.log('error:', error);
133 reject(error);
134 });
135
136 if (formData) {
137 formData.pipe(req as any);
138 const cReq = formData.submit(url!, (err, res) => {
139 cReq.end();
140 });
141 } else {
142 if (isFile) {
143 req.setHeader('Content-Type', 'application/octet-stream');
144 req.write(body);
145 } else {
146 // 发送请求体
147 if (body) {
148 req.setHeader('Content-Type', 'application/json');
149 req.write(typeof body === 'string' ? body : JSON.stringify(body));
150 }
151 }
152 req.end();
153 }
154 } catch (error) {
155 console.log('请求失败:', error);
156 reject(error);
157 }
158 });
159 };
160
161 export default requestNet;
162
162 lines TYPESCRIPT