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

.Net Core 2.2 阻止CORS预检请求,Angular调用加拿大邮政API如何解决?

问题根源

CORS是目标资源所在服务的跨域限制规则,你当前前端直接请求加拿大邮政的公开API,跨域限制由加拿大邮政的服务控制,你在自己.NET后端配置的CORS规则仅对你自己后端提供的接口生效,完全解决不了第三方API的跨域问题。
你之前禁用浏览器安全可正常请求,是因为绕过了浏览器自带的CORS校验逻辑,生产环境不可能要求用户关闭浏览器安全,所以该方案不可用。
另外你前端代码中额外添加的Access-Control-Allow-Origin、Access-Control-Allow-Methods属于响应头字段,不应该在前端请求头中携带,额外添加这些字段反而会增加预检请求的校验项,加剧问题。

解决方案

使用后端代理模式,流程如下:

  • 前端放弃直接调用加拿大邮政API,改为请求你自己的.NET后端接口
  • 后端新增一个转发接口,接收前端传递的参数后,在服务端发起对加拿大邮政API的请求,服务端请求不存在浏览器CORS限制
  • 后端拿到加拿大邮政返回的结果后,再返回给前端

前端代码修改

删除请求头中CORS相关的响应头字段,修改请求地址为自己后端的接口:

const httpOptions = {
    headers: new HttpHeaders({
      'Content-Type':  'application/json', // 传给自己后端用JSON更方便处理,也可直接传XML
      'Accept':  'application/json',
      'Accept-language': 'en-CA',
    }),
    responseType: 'text' as 'json'
};

// 组装参数传给后端
var postData = {
    weight:5,
    originPostalCode:'M5V0G1',
    destPostalCode:'M4R1L8'
}

// 请求自己的后端接口
this.http.post('/api/CanadaPost/GetRate', postData, httpOptions)
.subscribe(
    result => {    
        console.log(result);                 
    }, 
    error => console.log('There was an error: ', error)
);

后端修改配置

首先在Startup.cs的ConfigureServices方法中注册HttpClient:

services.AddHttpClient();

后端新增转发接口示例

using Microsoft.AspNetCore.Mvc;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;

[Route("api/[controller]")]
[ApiController]
public class CanadaPostController : ControllerBase
{
    private readonly IHttpClientFactory _httpClientFactory;
    public CanadaPostController(IHttpClientFactory httpClientFactory)
    {
        _httpClientFactory = httpClientFactory;
    }

    [HttpPost("GetRate")]
    public async Task<IActionResult> GetRate([FromBody] RateRequest request)
    {
        var client = _httpClientFactory.CreateClient();
        // 组装加拿大邮政要求的XML请求体
        var xmlContent = $@"<mailing-scenario xmlns=""https://www.canadapost.ca/ws/ship/rate-v4"">
                            <customer-number>0009669089</customer-number>
                            <parcel-characteristics>
                            <weight>{request.Weight} </weight>
                            </parcel-characteristics>
                            <origin-postal-code>{request.OriginPostalCode}</origin-postal-code>
                            <destination>
                            <domestic>
                            <postal-code>{request.DestPostalCode}</postal-code>
                            </domestic>
                            </destination>
                            </mailing-scenario>";
        // 设置符合加拿大邮政要求的请求头
        var content = new StringContent(xmlContent, Encoding.UTF8, "application/vnd.cpc.ship.rate-v4+xml");
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/vnd.cpc.ship.rate-v4+xml"));
        // 建议将鉴权密钥放到配置文件中,不要硬编码
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", "YTUxZGQ1MWY2YjJhNjE4ODowODgzOThiZTUxY2Y4Y2RjZTIzM34");
        client.DefaultRequestHeaders.AcceptLanguage.Add(new StringWithQualityHeaderValue("en-CA"));
        // 服务端发起请求,无CORS限制
        var response = await client.PostAsync("https://soa-gw.canadapost.ca/rs/ship/price", content);
        if (response.IsSuccessStatusCode)
        {
            var result = await response.Content.ReadAsStringAsync();
            // 可自行解析XML转成JSON返回给前端,也可直接返回XML内容
            return Ok(result);
        }
        return StatusCode((int)response.StatusCode, await response.Content.ReadAsStringAsync());
    }
}

// 前端传参接收类
public class RateRequest
{
    public decimal Weight { get; set; }
    public string OriginPostalCode { get; set; }
    public string DestPostalCode { get; set; }
}

你现有的Startup.cs的CORS配置无需修改,本身就可以支持前端调用你自己的后端接口。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.17 13:36:01