如何使用JavaScript实现基础SOAP API请求?
解决前端SOAP请求的CORS与415错误
问题核心
你遇到的矛盾本质是浏览器跨域安全限制:
- 携带
Content-Type: application/soap+xml; charset=utf-8头时,浏览器会自动发送OPTIONS预检请求,而目标服务器返回的Access-Control-Allow-Headers列表中未包含该Content-Type,导致请求被浏览器拦截。 - 不添加Content-Type头时,服务器无法识别请求的媒体类型,直接返回415错误。
- Reqbin能正常运行是因为它是在服务器端发起请求,不受浏览器CORS规则约束。
可行解决方案
方案1:搭建同域代理(生产环境推荐)
通过自己的后端服务转发SOAP请求,绕过浏览器的跨域限制。以Node.js + Express为例,代理代码示例:
const express = require('express'); const request = require('request'); const app = express(); // 解析SOAP请求体 app.use(express.raw({ type: 'application/soap+xml' })); // 代理接口 app.post('/proxy-tempconvert', (req, res) => { const targetUrl = 'https://www.w3schools.com/xml/tempconvert.asmx'; // 转发请求到目标接口 req.pipe(request.post({ url: targetUrl, headers: { 'Content-Type': req.headers['content-type'] } })).pipe(res); }); app.listen(3000, () => { console.log('代理服务运行在 http://localhost:3000'); });
修改前端JS代码,请求代理地址:
var url = "http://localhost:3000/proxy-tempconvert"; var xhr = new XMLHttpRequest(); xhr.open("POST", url); xhr.setRequestHeader("Content-Type", "application/soap+xml; charset=utf-8"); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { console.log(xhr.status); console.log(xhr.responseText); document.getElementById('result').textContent = xhr.responseText; } }; var data = `<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope"> <soap12:Body> <FahrenheitToCelsius xmlns="https://www.w3schools.com/xml/"> <Fahrenheit>75</Fahrenheit> </FahrenheitToCelsius> </soap12:Body> </soap12:Envelope>`; xhr.send(data);
方案2:适配SOAP 1.1格式(调试尝试)
部分ASMX接口优先支持SOAP 1.1,修改请求头和信封命名空间,尝试绕过预检拦截:
var url = "https://www.w3schools.com/xml/tempconvert.asmx"; var xhr = new XMLHttpRequest(); xhr.open("POST", url); // 使用SOAP 1.1的Content-Type xhr.setRequestHeader("Content-Type", "text/xml; charset=utf-8"); // ASMX接口通常需要SOAPAction头 xhr.setRequestHeader("SOAPAction", "https://www.w3schools.com/xml/FahrenheitToCelsius"); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { console.log(xhr.status); console.log(xhr.responseText); } }; // 替换为SOAP 1.1的命名空间 var data = `<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <FahrenheitToCelsius xmlns="https://www.w3schools.com/xml/"> <Fahrenheit>75</Fahrenheit> </FahrenheitToCelsius> </soap:Body> </soap:Envelope>`; xhr.send(data);
注:此方案依赖目标服务器的跨域配置,不一定能解决问题,但可作为调试尝试。
重要提示
浏览器的CORS扩展仅适合本地调试,生产环境必须通过代理或目标服务器配置合法的跨域规则解决问题。
内容的提问来源于stack exchange,提问作者Solv_it_kas
相关产品推荐
相关产品推荐

