Angular4中使用HttpClient调用API出现两次请求的解决方法
解决Angular HttpClient调用API出现两次请求(OPTIONS + GET)的问题
首先得跟你澄清:你看到的两次请求不是代码导致的重复API调用——第一次的OPTIONS请求是浏览器自带的跨域预请求(CORS Preflight Request),属于浏览器的安全机制,不是你的代码写错了。
为什么会出现OPTIONS请求?
当你的Angular应用运行的域名(比如默认的http://localhost:4200)和API所在的域名(你的http://localhost/MyProject/,端口是80)不一致时,浏览器会判定这是跨域请求。为了确保后端允许这个跨域请求,浏览器会自动先发送一个OPTIONS请求,询问后端:「我能不能用GET方法请求你?允许的头信息有哪些?」,只有后端返回允许的响应后,浏览器才会发送真正的GET请求获取数据。
怎么解决这个“两次请求”的问题?
根据你的场景,有两种常用方案:
方案一:后端配置CORS,缓存预请求结果
你需要在API后端(比如PHP、Node.js等服务)添加CORS响应头,让浏览器缓存预请求的结果,避免每次请求都先发OPTIONS:
- 设置
Access-Control-Allow-Origin:指定你的前端域名(比如http://localhost:4200,生产环境不要用*,不安全) - 设置
Access-Control-Allow-Methods:包含GET和OPTIONS方法 - 设置
Access-Control-Max-Age:设置一个缓存时长(比如86400,也就是24小时),这样浏览器在有效期内不会重复发送OPTIONS请求
举个PHP后端的示例代码:
header("Access-Control-Allow-Origin: http://localhost:4200"); header("Access-Control-Allow-Methods: GET, OPTIONS"); header("Access-Control-Max-Age: 86400"); // 如果你的请求有自定义头信息,还需要添加Access-Control-Allow-Headers
方案二:用Angular代理转发请求(推荐开发环境使用)
这种方式让浏览器认为是同域请求,直接跳过OPTIONS预请求:
- 在Angular项目根目录创建
proxy.conf.json文件,内容如下:
{ "/MyProject/*": { "target": "http://localhost", "secure": false, "changeOrigin": true } }
- 修改
package.json里的启动命令,加上代理配置:
"start": "ng serve --proxy-config proxy.conf.json"
- 把
UserService里的apiUrl改成相对路径:
apiUrl : any='/MyProject/';
之后启动项目,Angular会自动把前端的请求代理到后端API,浏览器会判定为同域请求,不会再发送OPTIONS预请求。
额外检查:确认代码没有真的重复调用
如果上面的方案都试过还是有两次GET请求,那就要检查代码是否真的调用了两次API:
- 确认
ngOnInit里只调用了一次getResult() - 检查模板里有没有用异步管道(比如
| async)重复订阅Observable - 检查有没有多次调用
subscribe方法
从你提供的代码来看,组件和服务的逻辑都是正常的,没有重复调用的问题,所以大概率是CORS预请求导致的“两次请求”,按照上面的方案处理就可以了。
内容的提问来源于stack exchange,提问作者Harleen Kaur Arora
相关产品推荐
相关产品推荐

