使用async/await重构Yelp API fetch请求及相关疑问解答
Yelp API 调用问题解答
1. 关于async/await语法的使用
async/await确实是当前前端异步逻辑的通用开发实践,教程选择.then链式写法通常是为了降低学习门槛,照顾对Promise进阶语法不熟悉的初学者,两种写法本质都是基于Promise的异步实现,没有功能层面的优劣差异,只是编码风格不同。
2. 关于Authorization: Bearer头的作用
- Bearer令牌是OAuth2身份验证体系中的标准密钥传递方式,放在请求头里比放在URL中安全程度高很多:URL会被浏览器历史、服务器日志、中间代理节点全链路记录,密钥极易泄露,放在请求头则不会被常规日志默认采集。
- 不可以把apiKey直接放在URL里,一方面Yelp的API接口不支持这种鉴权方式,另一方面会导致密钥直接泄露,造成API配额被盗刷、账号被封禁的风险。
3. 关于错误处理逻辑
教程省略错误处理是为了简化示例代码,只突出核心请求逻辑,实际项目中必须补充错误处理:
- 原有
.then链式写法可以直接在最后一个.then之后追加.catch()捕获异步错误 - 额外注意:fetch API只有网络层面的错误(比如断网、请求超时)才会触发reject,HTTP状态码为4xx/5xx的业务错误不会进入catch,所以需要先判断
response.ok再解析返回数据 - 如果换成async/await写法,用try/catch包裹整个请求逻辑即可。
4. 关于cors-anywhere前缀的作用
这个前缀是用来解决浏览器*同源策略(CORS)*限制的:Yelp的API没有开放前端跨域调用权限,直接在浏览器中请求会被拦截,cors-anywhere是公共代理服务,会转发你的请求并返回带跨域允许头的响应,它本身不提供任何安全能力,反而会把你的API密钥透传给代理服务,完全不能用于生产环境。
部署到Netlify时不能直接去掉前缀,直接请求Yelp接口依然会触发跨域限制,正确的生产重构方案是用Netlify的Serverless函数做代理:
- 把API密钥存在Netlify的环境变量中,不暴露在前端代码里
- 编写Serverless函数接收前端参数,由函数后端发起对Yelp API的请求
- 前端只请求自己的Netlify函数,由函数把Yelp返回的结果回传给前端,同时解决跨域和密钥泄露问题。
优化后的请求代码(开发环境版)
修复了原代码中business.categories.title的bug(categories是数组,需要取第一个分类的title),补充了错误处理、参数编码和async/await写法:
const apiKey = 'your yelp api key'; // 开发环境用代理地址,生产环境替换为自己的Netlify函数地址 const baseUrl = 'https://cors-anywhere.herokuapp.com/https://api.yelp.com/v3/businesses/search'; const Yelp = { async searchYelp(term, location, sortBy) { try { const response = await fetch(`${baseUrl}?term=${encodeURIComponent(term)}&location=${encodeURIComponent(location)}&sort_by=${sortBy}`, { headers: { Authorization: `Bearer ${apiKey}` }, }); // 先判断HTTP请求是否成功 if (!response.ok) { throw new Error(`请求失败,状态码:${response.status}`); } const jsonResponse = await response.json(); if (!jsonResponse.businesses) return []; return jsonResponse.businesses.map((business) => ({ id: business.id, imageSrc: business.image_url, name: business.name, address: business.location.address1, city: business.location.city, state: business.location.state, zipCode: business.location.zip_code, // 修复原代码的bug:categories是数组,取第一个分类的标题 category: business.categories?.[0]?.title || '未知分类', rating: business.rating, reviewCount: business.review_count, })) } catch (error) { // 这里可以根据需求统一处理错误,比如弹窗提示、上报等 console.error('调用Yelp接口失败:', error); throw error; // 把错误抛出给调用方处理 } } } export default Yelp
内容的提问来源于stack exchange,提问作者Halp_am_stuck
相关产品推荐
相关产品推荐

