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

如何通过JavaScript动态加载ViewComponent?请求报错排查

问题分析与修正方案

你的代码存在几个关键问题,直接导致了这两个错误,下面逐一说明并给出修复方法:

1. URL解析失败,请求空地址

你在JS里使用了@Url.Action Razor语法,但如果这段JS是放在独立的.js文件中,ASP.NET不会解析Razor代码,最终url变量会变成字符串'@Url.Action("GetReportViewComponent", "MyController")',而非实际的API路由地址,这就引发了第一个"Failed to load ''"的错误。

修正方法:

  • 若JS代码写在.cshtml文件内,确保Razor语法能被正常解析;
  • 若为独立JS文件,在.cshtml中提前生成好URL并通过全局变量传递:
    <script>
      window.reportApiUrl = '@Url.Action("GetReportViewComponent", "MyController")';
    </script>
    
    然后在JS中使用:let url = window.reportApiUrl;

2. 请求体未序列化,参数绑定失败

你直接将JS对象filterPanelOptions作为fetch的body传递,但fetch不会自动把对象转换为JSON格式,服务器无法正确绑定到FilterOptions模型,导致请求异常,触发HTTP2协议错误。

修正方法:
把body序列化为JSON字符串,同时添加Content-Type头声明请求格式:

body: JSON.stringify(filterPanelOptions),
headers: {
  // ...其他头信息
  "Content-Type": "application/json"
}

3. 错误的请求头配置

  • Access-Control-Allow-Origin是服务器返回的响应头,客户端设置这个完全无效,直接删除;
  • accept设为application/json不合理,因为控制器返回的是ViewComponent的HTML内容,应改为text/html,或者直接去掉该头;
  • crossDomain不是fetch的合法配置项,属于多余设置,删除即可。

修正后的JS代码示例

function filterPanelChanged(e) {
    let filterPanelOptions = e.detail;

    if (filterPanelOptions.viewReport) {
        $('#reports-section').empty();

        let url = window.reportApiUrl;
        
        fetch(url, {
            method: "POST",
            headers: {
                Authorization: "Bearer " + window.Auth.AccessToken,
                "Content-Type": "application/json",
                "accept": "text/html"
            },
            body: JSON.stringify(filterPanelOptions)
        }).then(function (response) {
            if (response.ok) {
                response.text().then(function (result) {
                    console.log(result);
                    $('#reports-section').html(result);
                    $('#reports-section').show();
                });
            } else {
                console.error('请求失败,状态码:', response.status);
            }
        }).catch(function(error) {
            console.error('网络错误:', error);
        });
    } else {
        $("#reports-section").hide();
    }
}

控制器额外注意点

确保前端传递的属性名称和后端FilterOptions类的属性完全一致(JSON大小写敏感),可以通过JsonPropertyName特性显式映射,同时用[FromBody]明确指定从请求体绑定参数:

[HttpPost]
public IActionResult GetReportViewComponent([FromBody] FilterOptions filterOptions)
{    
    return this.ViewComponent("ReportViewer", new
    {
        Name = "Reports/MyReport.repx",
        Parameters = $"param1={filterOptions.Param1}&ActiveDate=2023-02-01&param2={filterOptions.Param2}&param3={filterOptions.Param3}",
        ShowParameters = false
    });
}

public class FilterOptions
{
    [JsonPropertyName("param1")]
    public long Param1{ get; set; }

    [JsonPropertyName("param2")]
    public long Param2{ get; set; }

    [JsonPropertyName("param3")]
    public long? Param3{ get; set; }

    [JsonPropertyName("activeDate")]
    public DateTime? ActiveDate { get; set; }
}

内容的提问来源于stack exchange,提问作者Donald N. Mafa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 08:32:47