Angular 5中能否不通过查询字符串用JSONP提交Body数据?
问题分析:JSONP为何无法传递Body参数?
兄弟,你遇到的这个问题其实是JSONP的天生短板——它从根儿上就没法带请求体,跟Angular 5没关系!
JSONP的核心原理是通过动态插入<script>标签实现跨域请求,而浏览器通过<script>发起的请求只能是GET请求。GET请求的设计就不支持请求体(Body),所有参数只能拼在URL的查询字符串里。这是JSONP的机制限制,不管用哪个框架的JSONP实现,都绕不开这个问题。所以你现在用Angular 5的jsonp()方法,确实没法传Body,只能走查询字符串,数据量大的话这个方案肯定不可行。
最优解决方案:前端代理服务器(无需修改服务端)
既然你没法控制服务端修改CORS配置,那最靠谱的办法就是搭一个前端代理——让你的Angular应用先请求自己的代理服务器,再由代理服务器去请求目标WebService。这样跨域问题直接消失,还能正常用POST请求传递大体积的Body参数。
具体在Angular 5中配置代理的步骤:
- 在项目根目录新建
proxy.conf.json文件,填入以下配置:
{ "/proxy-api": { "target": "https://你的目标WebService域名.com", "secure": false, // 如果目标服务是HTTPS且证书不被信任,设为false "changeOrigin": true, // 必须开启,否则服务端会识别出请求来自代理而非浏览器 "pathRewrite": { "^/proxy-api": "" // 可选:如果需要去掉请求路径里的/proxy-api前缀,比如把/proxy-api/xxx转成/xxx } } }
- 打开项目根目录的
.angular-cli.json(Angular 5的配置文件),找到defaults.serve节点,添加proxyConfig配置:
"defaults": { "serve": { "proxyConfig": "proxy.conf.json" } }
- 重启你的Angular开发服务器,之后就可以用
HttpClient的post方法正常传Body了:
import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; @Injectable() export class DataService { constructor(private http: HttpClient) {} submitLargeData(yourData: any) { // 这里的/proxy-api会被代理转发到目标服务 return this.http.post('/proxy-api/你的接口路径', yourData); } }
这样一来,前端请求先到代理,代理再转发到目标WebService,完全不存在跨域问题,而且可以轻松传递大体积的请求体。
备选思路(如果没法搭建代理)
如果因为环境限制没法搭代理,那只能试试这两个不太理想的方案:
- 压缩查询参数:把大体积数据用Base64等方式压缩后拼到查询字符串里,但还是会受限于浏览器的URL长度上限(一般是2KB-8KB)
- 检查服务端是否支持表单POST:如果服务端接受表单提交,或许可以尝试,但还是需要解决跨域问题,本质上还是得靠代理
不过说实话,这些备选方案都不如代理方案稳定可靠。
内容的提问来源于stack exchange,提问作者Pawan Pillai
相关产品推荐
相关产品推荐

