You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用Kazpost WSDL接口时XMLHttpRequest readyState=4但status=0问题求助

解决XMLHttpRequest请求Kazpost SOAP接口时status为0的问题

首先,你遇到的readyState=4但status=0的问题,绝大多数情况是浏览器同源策略(CORS)限制导致的,再加上你可能搞错了请求地址,这两个因素共同引发了失败。下面给你拆解问题和解决方案:

核心问题分析

  1. 跨域限制:浏览器不允许前端页面直接请求不同域名的接口(除非目标服务器配置了CORS响应头)。你请求的http://rates.kazpost.kz和你的页面域名不属于同源,浏览器会拦截这个请求,最终返回status=0。
  2. 请求地址错误:你当前请求的是WSDL文档的地址(postratesws.wsdl),但实际调用SOAP接口应该请求服务的端点地址——你需要打开这个WSDL文件,找到<soap:address location="..." />标签里的URL,那才是真正的接口调用地址。

解决方案

方案1:搭建后端代理(最可靠的解决方式)

前端直接跨域请求几乎绕不开浏览器的限制,所以推荐在你的后端搭建一个代理服务:

  • 前端请求你自己的后端接口(同源,不会被拦截)
  • 后端再去调用Kazpost的SOAP接口(后端不受浏览器同源策略限制)
  • 后端把接口返回的结果转发给前端

举个简单的Node.js/Express代理示例(你可以根据自己的后端技术栈调整):

const express = require('express');
const request = require('request');
const app = express();

app.use(express.text({ type: 'text/xml' }));

app.post('/proxy-kazpost-rate', (req, res) => {
  // 替换成WSDL里找到的实际SOAP端点地址
  const kazpostEndpoint = 'http://rates.kazpost.kz/postratesprodv2/postratesws';
  request.post({
    url: kazpostEndpoint,
    body: req.body,
    headers: { 'Content-Type': 'text/xml' }
  }, (err, response, body) => {
    if (err) {
      res.status(500).send(err);
      return;
    }
    res.set('Content-Type', 'text/xml');
    res.send(body);
  });
});

app.listen(3000, () => console.log('Proxy server running on port 3000'));

然后修改你的前端代码,把请求地址改成代理地址:

var xmlhttp = new XMLHttpRequest();
// 改成你的代理接口地址
xmlhttp.open('POST', 'http://localhost:3000/proxy-kazpost-rate', true); 

// 后面的SOAP请求体保持不变
var sr = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:pos="http://webservices.kazpost.kz/postratesws">' +
         '<soapenv:Header/>' +
         '<soapenv:Body>' +
         '<pos:GetPostRateRequest>' +
         '<pos:GetPostRateInfo>' +
         '<pos:SndrCtg>1</pos:SndrCtg>' +
         '<pos:Product>P102</pos:Product>' +
         '<pos:MailCat>1</pos:MailCat>' +
         '<pos:SendMethod>2</pos:SendMethod>' +
         '<pos:Weight>750</pos:Weight>' +
         '<pos:Dimension>s</pos:Dimension>' +
         '<pos:Value>100</pos:Value>' +
         '<pos:From>050031</pos:From>' +
         '<pos:To>010001</pos:To>' +
         '<pos:ToCountry>au</pos:ToCountry>' +
         '</pos:GetPostRateInfo>' +
         '</pos:GetPostRateRequest>' +
         '</soapenv:Body>' +
         '</soapenv:Envelope>';

xmlhttp.onreadystatechange = function () {
  if (xmlhttp.readyState == 4) {
    if (xmlhttp.status == 200) {
      console.log('请求成功,响应内容:', xmlhttp.responseText);
    } else {
      console.error('请求失败,状态码:', xmlhttp.status, '状态信息:', xmlhttp.statusText);
    }
  }
}

xmlhttp.setRequestHeader('Content-Type', 'text/xml');
xmlhttp.send(sr);

方案2:检查并修正SOAP端点地址

先确认你请求的URL是否正确:打开http://rates.kazpost.kz/postratesprodv2/postratesws.wsdl,找到类似下面的标签:

<soap:address location="http://rates.kazpost.kz/postratesprodv2/postratesws"/>

把这个location里的URL作为你的请求地址,替换掉当前的.wsdl地址。不过即使地址正确,跨域问题仍然存在,所以还是需要结合代理方案。

调试建议

打开浏览器开发者工具的Network面板,查看这个请求的详细信息:

  • 如果看到CORS相关的报错,那就是跨域问题实锤了
  • 如果看到404错误,说明你请求的地址(WSDL文件)不是正确的接口端点

内容的提问来源于stack exchange,提问作者GoldenScrew

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 09:08:23