如何通过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并通过全局变量传递:
然后在JS中使用:<script> window.reportApiUrl = '@Url.Action("GetReportViewComponent", "MyController")'; </script>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¶m2={filterOptions.Param2}¶m3={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
相关产品推荐
相关产品推荐

