Angular 5发送Post请求遇Cross-Origin Request Blocked问题求助
解决Angular 5请求第三方API的CORS跨域问题
你遇到的这个错误是典型的CORS预检请求失败问题——浏览器的同源策略阻止了跨域请求,因为目标服务器api.textlocal.in的CORS响应头里缺少了必要的access-control-allow-headers配置,没法匹配你的请求所携带的头部信息。下面给你几个可行的解决思路:
1. 优先让第三方API配置正确的CORS头(根本解决方案)
CORS是完全由服务器端控制的机制,所以最彻底的办法是让textlocal的API团队调整他们的CORS配置:
- 在响应的预检OPTIONS请求时,添加
Access-Control-Allow-Headers头,包含你的请求中用到的所有自定义头或标准头(比如Content-Type、Authorization等)。 - 同时确保他们的CORS配置里包含
Access-Control-Allow-Origin,允许你的前端域名访问。
不过如果textlocal是第三方公共API,你可能没法直接修改他们的配置,那可以试试下面的前端/中转方案。
2. 开发环境使用Angular代理转发
Angular CLI自带了代理功能,能帮你在开发阶段绕过跨域限制,步骤如下:
- 在项目根目录创建
proxy.conf.json文件,内容如下:{ "/textlocal-api": { "target": "https://api.textlocal.in", "secure": true, "changeOrigin": true, "pathRewrite": { "^/textlocal-api": "" } } } - 修改
angular.json里的serve配置,添加代理文件路径:"serve": { "builder": "@angular-devkit/build-angular:dev-server", "options": { "browserTarget": "your-project-name:build", "proxyConfig": "proxy.conf.json" // 新增这一行 }, // ...其他配置 } - 重启Angular开发服务器,然后把你的请求URL改成:
这样开发时,Angular会自动把请求转发到this.httpClient.post("/textlocal-api/send/", new Message(this.apiKey, "xxxxxxxxx", "TEST", "SOIS_App"))https://api.textlocal.in/send/,浏览器就不会触发跨域限制了。
3. 生产环境搭建后端中转服务
生产环境不能依赖Angular代理,这时候建议你搭建一个自己的后端中转接口,让前端请求自己的后端,再由后端去调用textlocal的API——后端之间的请求不受浏览器同源策略限制。
举个简单的Node.js/Express中转例子:
const express = require('express'); const axios = require('axios'); const cors = require('cors'); const app = express(); app.use(cors()); // 允许你的前端域名访问中转服务 app.use(express.json()); app.post('/send-sms', async (req, res) => { try { // 转发请求到textlocal API const response = await axios.post('https://api.textlocal.in/send/', req.body, { headers: { // 这里根据需要设置textlocal要求的头信息 'Content-Type': 'application/json' } }); res.json(response.data); } catch (error) { res.status(error.response?.status || 500).json(error.response?.data || { message: '请求失败' }); } }); app.listen(3001, () => console.log('中转服务运行在http://localhost:3001'));
然后前端请求改成:
this.httpClient.post("http://your-server-domain:3001/send-sms", new Message(this.apiKey, "xxxxxxxxx", "TEST", "SOIS_App"))
内容的提问来源于stack exchange,提问作者PiotrKowalski
相关产品推荐
相关产品推荐

