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

ASP.NET Core Web API返回MP4时Angular调用报错求助

问题:Angular调用ASP.NET Core Web API下载MP4时出现net::ERR_FAILED 200错误

直接在浏览器粘贴API地址可正常下载MP4视频,但通过Angular调用时触发以下错误:

浏览器错误:net::ERR_FAILED 200

Angular返回的错误详情:

{
    "headers": {
        "normalizedNames": {},
        "lazyUpdate": null,
        "headers": {}
    },
    "status": 0,
    "statusText": "Unknown Error",
    "url": "https://localhost:5001/YouTube/DownloadVideoMp4Async/xU2U73Tk-DM",
    "ok": false,
    "name": "HttpErrorResponse",
    "message": "Http failure response for https://localhost:5001/YouTube/DownloadVideoMp4Async/xU2U73Tk-DM: 0 Unknown Error",
    "error": {
        "isTrusted": true
    }
}

以下是调用代码和API实现:

Angular调用代码

downloadVideoMp4(url: string): Observable<Blob> {
    var RequestData = {
      url: url,
      type: 0
    }
    const headers = new HttpHeaders({
      'Content-Type': 'video/mp4',
      'Accept': 'video/mp4'
    });
    return this.http.get<Blob>(this.endpoint + url, {headers: headers, responseType: 'blob' as 'json' });
}

ASP.NET Core Web API代码

[HttpGet]
[Route("DownloadVideoMp4Async/{videoLink}")]
public async Task<ActionResult<HttpResponseMessage>> DownloadVideoMp4Async(string videoLink)
{
    try
    {
        // Approach 1
        var memory = new MemoryStream();

        using (var file = new FileStream(pathToFile, FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            await file.CopyToAsync(memory);
        }

        memory.Position = 0;
        var ext = Path.GetExtension(pathToFile).ToLowerInvariant();

        return File(memory, "video/mp4", $"{video.Title}.mp4");
            
        // Approach 2
        // var stream = new FileStream(pathToFile, FileMode.Open, FileAccess.Read);
        // var result = new HttpResponseMessage(HttpStatusCode.OK)
        // {
        //    Content = new StreamContent(stream)
        // };
        // result.Content.Headers.ContentType = new MediaTypeHeaderValue("video/mp4");
        // result.Content.Headers.ContentRange = new ContentRangeHeaderValue(0, stream.Length);
        // result.Content.Headers.Add("filename", $"{video.Title}.mp4");

        // return result;
    }
    catch (Exception ex)
    {
        return new HttpResponseMessage() { StatusCode = HttpStatusCode.InternalServerError };
    }
}

问题排查与解决方案

1. 修正Angular请求配置

  • 移除Content-Type头:GET请求无请求体,该头属于冗余配置,可能导致解析异常。
  • 修正responseType设置:直接指定为'blob',无需强制转为'json'。

修改后的Angular代码:

downloadVideoMp4(url: string): Observable<Blob> {
    const headers = new HttpHeaders({
      'Accept': 'video/mp4'
    });
    return this.http.get<Blob>(this.endpoint + url, { 
        headers: headers, 
        responseType: 'blob' as 'blob' 
    });
}

2. 规范API返回类型

API方法返回Task<ActionResult<HttpResponseMessage>>属于错误用法,ASP.NET Core中直接返回IActionResult即可适配File()方法的返回值。

修改后的API代码:

[HttpGet]
[Route("DownloadVideoMp4Async/{videoLink}")]
public async Task<IActionResult> DownloadVideoMp4Async(string videoLink)
{
    try
    {
        var memory = new MemoryStream();

        using (var file = new FileStream(pathToFile, FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            await file.CopyToAsync(memory);
        }

        memory.Position = 0;
        return File(memory, "video/mp4", $"{video.Title}.mp4");
    }
    catch (Exception ex)
    {
        return StatusCode(StatusCodes.Status500InternalServerError);
    }
}

3. 跨域配置检查

若API与Angular不在同一域名,需确保ASP.NET Core已配置CORS:

// Program.cs中添加
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowAngular",
        policy => policy.WithOrigins("http://localhost:4200") // 替换为你的Angular端口
                        .AllowAnyHeader()
                        .AllowAnyMethod());
});

// 在app.UseRouting()之后启用CORS
app.UseCors("AllowAngular");

4. 大文件下载优化

若视频文件过大,可添加分块传输支持(ASP.NET Core默认已处理),或在Angular中配置超时:

// 示例:添加超时配置
import { timeout } from 'rxjs/operators';

downloadVideoMp4(url: string): Observable<Blob> {
    const headers = new HttpHeaders({
      'Accept': 'video/mp4'
    });
    return this.http.get<Blob>(this.endpoint + url, { 
        headers: headers, 
        responseType: 'blob' as 'blob' 
    }).pipe(timeout(300000)); // 5分钟超时
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 16:55:27