使用VueJs 在Axios 中,当responseType 为blob 时,如何读取http 错误?

Sai*_*Sai 13 json blob laravel vue.js axios

我在我的 VueJS 应用程序中使用 blob responseType 和 Axios 从服务器下载文档。当响应代码为 200 时,它可以正常工作并下载文件,但是当出现任何 http 错误时,我无法在捕获错误时读取状态代码,因为该错误是 JSON 响应。

有没有人遇到过类似的问题,并找到了一种将 blob 响应类型转换为 json 并根据状态代码抛出错误的方法?

我尝试从 Laravel 后端以纯文本形式发送响应,并尝试在前端将响应转换为 JSON 或文本,但没有成功。

我曾尝试阅读错误响应标头,但没有成功。

公理({
        网址:'xxx',
        方法:'获取',
        responseType: 'blob', 
        })
    .then((响应) => {
        //代码读取响应并使用blob创建对象url并下载文档
    })
    .catch((错误) => {
      console.log('错误', error.message); //没有
      console.log('错误', error.error); //不明确的
      console.log('错误', error.data); //不明确的

      const blb = new Blob([error], {type: "text/plain"});
      const reader = new FileReader();

      // 在读取/加载 blob 后触发。
      reader.addEventListener('loadend', (e) => {
        const text = e.srcElement.result;
        控制台日志(文本);
      });
     // 开始以文本形式读取 blob。
     reader.readAsText(blb);
});

我只想根据状态代码抛出错误消息。如果它是 401 只是希望它未经授权而其他任何东西都将它扔到组件上。

guy*_*oni 20

原因是响应类型是blob
如果出现错误,可以直接在异常对象中获取状态代码。然而,回应是一个承诺。

你需要做的是:

.catch((error) => {
    let statusCode = error.response.status
    let responseObj = await error.response.data.text();
       :
       :
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,您可以阅读文档

  • 只需将responseObj解析为JSON,然后也许可以在它周围抛出一个try catch...但是谢谢,为我节省了很多Reader的东西。 (2认同)

小智 9

你可以这样做,如果它是一个 blob,它会将错误转换为 JSON,或者让响应数据按接收到的方式传输,你可以使用它。

  let errorString = error.response.data;
  if (
      error.request.responseType === 'blob' &&
      error.response.data instanceof Blob &&
      error.response.data.type &&
      error.response.data.type.toLowerCase().indexOf('json') != -1
  ) {
    errorString = JSON.parse(await error.response.data.text());
  }
  
  alert(errorString);
Run Code Online (Sandbox Code Playgroud)


tuh*_*n47 5

您需要将响应 blob 转换为 json:

Axios({
    url: 'xxxx',
    method: 'GET',
    responseType: 'blob',
  })
  .then((response) => {
    //code to read the response and create object url with the blob and download the document
  })
  .catch((error) => {
    if (
      error.request.responseType === 'blob' &&
      error.response.data instanceof Blob &&
      error.response.data.type &&
      error.response.data.type.toLowerCase().indexOf('json') != -1
    ) {
      new Promise((resolve, reject) => {
          let reader = new FileReader();
          reader.onload = () => {
            error.response.data = JSON.parse(reader.result);
            resolve(Promise.reject(error));
          };

          reader.onerror = () => {
            reject(error);
          };

          reader.readAsText(error.response.data);
        })
        .then(err => {
          // here your response comes
          console.log(err.response.data)
        })
    };
  });
Run Code Online (Sandbox Code Playgroud)

您可以在拦截器内部使用它。欲了解更多信息


ros*_*per 1

我相信您可能错误地使用了error变量catch()

Axios 传递一个错误对象,该对象具有一个response属性,您可以在该属性中查找errormessage

https://github.com/axios/axios#handling-errors

顺便说一句,如果您可以捕获服务器端的错误,您可以尝试将Content-type标头设置为text/plain. 使用header('Content-Type: plain/text')Laravel 的响应方法