
前言在当今的前后端分离开发模式下HTTP请求是前端与后端通信的基石。随着大语言模型LLM的普及掌握如何高效调用HTTP接口变得尤为重要。本文将带你深入了解前端HTTP请求的多种方式并通过实战案例展示如何使用OpenAI SDK和原生fetch调用LLM接口。一、前端发送HTTP请求的常见方式1.1 XMLHttpRequestXHRXMLHttpRequest是浏览器最早提供的异步通信API虽然较为底层但功能完善。const xhr new XMLHttpRequest(); xhr.open(GET, https://api.example.com/data); xhr.onreadystatechange function() { if (xhr.readyState 4 xhr.status 200) { console.log(JSON.parse(xhr.responseText)); } }; xhr.send();1.2 Fetch API现代推荐Fetch是ES6引入的现代替代方案基于Promise设计语法更简洁。// GET请求 fetch(https://api.example.com/data) .then(response response.json()) .then(data console.log(data)) .catch(error console.error(Error:, error)); // POST请求 fetch(https://api.example.com/data, { method: POST, headers: { Content-Type: application/json, }, body: JSON.stringify({ key: value }) }) .then(response response.json()) .then(data console.log(data));1.3 第三方库Axios等在实际项目中我们常使用封装更完善的第三方库。// Axios示例 axios.get(https://api.example.com/data) .then(response console.log(response.data)) .catch(error console.error(error));二、编程模式解析2.1 前后端分离架构这是一种将前端UI层与后端业务逻辑层分离的开发模式前端负责界面渲染、用户交互后端提供RESTful API或GraphQL接口通信通过HTTP/HTTPS协议进行数据交换2.2 异步编程与Async/Awaitasync function fetchData() { try { const response await fetch(https://api.example.com/data); const data await response.json(); console.log(data); } catch (error) { console.error(请求失败:, error); } }核心优势非阻塞不会阻塞主线程流畅体验用户操作不受影响资源高效充分利用浏览器性能2.3 B/S vs C/S架构架构类型特点代表应用B/SBrowser/Server无需安装通过浏览器访问Web应用、小程序C/SClient/Server需要安装客户端功能更强大手机App、桌面软件三、服务器与网络基础3.1 理解服务器地址http://127.0.0.1:3000/api/v1/chat ├───┬─── ─┬─ ──┬─── ───┬───── │ │ │ │ └─ API端点路径 │ │ │ └─ 端口号3000 │ │ └─ IP地址本地回环 │ └─ 协议HTTP └─ 域名如www.baidu.comIP地址网络层的唯一标识域名用户友好的访问方式DNS解析将域名转换为IP地址3.2 API端点EndpointAPI端点是服务的具体访问地址通常遵循RESTful设计规范GET /api/users # 获取用户列表 POST /api/users # 创建用户 GET /api/users/:id # 获取特定用户 PUT /api/users/:id # 更新用户 DELETE /api/users/:id # 删除用户四、实战调用LLM HTTP接口4.1 使用OpenAI SDK官方推荐import OpenAI from openai; const openai new OpenAI({ apiKey: your-api-key, baseURL: https://api.openai.com/v1 }); async function chatWithGPT() { try { const completion await openai.chat.completions.create({ model: gpt-3.5-turbo, messages: [ { role: system, content: 你是一个AI助手 }, { role: user, content: 请介绍一下HTTP协议 } ], temperature: 0.7, max_tokens: 1000 }); console.log(completion.choices[0].message.content); return completion; } catch (error) { console.error(LLM调用失败:, error); throw error; } }4.2 使用原生Fetch调用async function callLLMWithFetch() { const API_URL https://api.openai.com/v1/chat/completions; const API_KEY your-api-key; const requestData { model: gpt-3.5-turbo, messages: [ { role: system, content: 你是一个专业的编程助手 }, { role: user, content: 写一个JavaScript的HTTP请求示例 } ], temperature: 0.7, max_tokens: 500 }; try { const response await fetch(API_URL, { method: POST, headers: { Content-Type: application/json, Authorization: Bearer ${API_KEY} }, body: JSON.stringify(requestData) }); if (!response.ok) { throw new Error(HTTP error! status: ${response.status}); } const data await response.json(); console.log(AI响应:, data.choices[0].message.content); return data; } catch (error) { console.error(请求失败:, error); throw error; } }4.3 流式响应处理对于LLM对话流式响应能提供更好的用户体验async function streamingLLMCall() { const response await fetch(https://api.openai.com/v1/chat/completions, { method: POST, headers: { Content-Type: application/json, Authorization: Bearer ${API_KEY} }, body: JSON.stringify({ model: gpt-3.5-turbo, messages: [{ role: user, content: 讲一个故事 }], stream: true // 启用流式响应 }) }); const reader response.body.getReader(); const decoder new TextDecoder(); let fullText ; while (true) { const { done, value } await reader.read(); if (done) break; const chunk decoder.decode(value); const lines chunk.split(\n).filter(line line.trim()); for (const line of lines) { if (line.startsWith(data: )) { const data line.slice(6); if (data [DONE]) continue; try { const parsed JSON.parse(data); const content parsed.choices[0]?.delta?.content; if (content) { fullText content; // 更新UI显示 console.log(实时输出:, content); } } catch (e) { console.error(解析错误:, e); } } } } console.log(完整响应:, fullText); return fullText; }五、数据处理与渲染5.1 数据转换示例// 假设从API获取的用户数据 const apiResponse { users: [ { id: 1, name: 张三, age: 25 }, { id: 2, name: 李四, age: 30 }, { id: 3, name: 王五, age: 28 } ] }; // 转换为表格行数据 function renderUserTable(data) { const tableRows data.users.map(user tr td${user.id}/td td${user.name}/td td${user.age}/td /tr ).join(); document.getElementById(userTable).innerHTML tableRows; }5.2 错误处理最佳实践async function robustAPICall(url, options {}) { try { const response await fetch(url, { ...options, headers: { Content-Type: application/json, ...options.headers } }); // 检查HTTP状态 if (!response.ok) { const errorData await response.json().catch(() ({})); throw new Error( errorData.message || HTTP ${response.status}: ${response.statusText} ); } // 检查Content-Type const contentType response.headers.get(content-type); if (contentType contentType.includes(application/json)) { return await response.json(); } return await response.text(); } catch (error) { console.error(API调用失败:, { url, error: error.message, stack: error.stack }); throw error; } }六、性能优化建议6.1 请求缓存策略class APICache { constructor(ttl 60000) { // 默认缓存1分钟 this.cache new Map(); this.ttl ttl; } async fetch(url, options {}) { const cacheKey ${url}_${JSON.stringify(options)}; const cached this.cache.get(cacheKey); if (cached Date.now() - cached.timestamp this.ttl) { return cached.data; } const response await fetch(url, options); const data await response.json(); this.cache.set(cacheKey, { data, timestamp: Date.now() }); return data; } }6.2 请求防抖与节流// 防抖用户停止输入后才发起请求 function debounce(fn, delay 300) { let timer null; return function(...args) { clearTimeout(timer); timer setTimeout(() fn.apply(this, args), delay); }; } const searchWithDebounce debounce(async (keyword) { const response await fetch(/api/search?q${keyword}); return response.json(); }, 500);七、常见问题与解决方案7.1 CORS跨域问题// 服务端设置Node.js Express app.use((req, res, next) { res.header(Access-Control-Allow-Origin, *); res.header(Access-Control-Allow-Methods, GET, POST, PUT, DELETE); res.header(Access-Control-Allow-Headers, Content-Type, Authorization); next(); });7.2 超时处理function fetchWithTimeout(url, options {}, timeout 5000) { return Promise.race([ fetch(url, options), new Promise((_, reject) setTimeout(() reject(new Error(请求超时)), timeout) ) ]); }八、总结本文全面介绍了前端HTTP请求的各个方面基础方法XMLHttpRequest和Fetch API编程模式前后端分离、异步编程、B/S架构网络基础IP、端口、域名、API端点实战应用LLM接口调用OpenAI SDK Fetch数据处理JSON转换、错误处理性能优化缓存、防抖节流掌握这些知识你将能够灵活运用各种HTTP请求方式高效调用LLM等第三方API构建健壮的前端应用优化网络请求性能