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

0s0u357o  于 2023-01-05  发布在  iOS
关注(0)|答案(6)|浏览(437)

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

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

我试过从Laravel后端以纯文本发送响应,并尝试在前端将响应转换为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) => {
      console.log('Error', error.message); //nothing
      console.log('Error', error.error); //undefined
      console.log('Error', error.data); //undefined

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

      // This fires after the blob has been read/loaded.
      reader.addEventListener('loadend', (e) => {
        const text = e.srcElement.result;
        console.log(text);
      });
     // Start reading the blob as text.
     reader.readAsText(blb);
});

我只想抛出基于状态码的错误信息,如果是401,只希望它是未授权的,或者其他任何东西,把它扔到组件上。

bvk5enib

bvk5enib1#

原因是响应类型为blob
如果出现错误,状态代码可直接在例外对象中使用。但是,响应是一个承诺。
你需要做的是:

.catch((error) => {
    let statusCode = error.response.status
    let responseObj = await error.response.data.text();
       :
       :

有关详细信息,请阅读文档。

jchrr9hc

jchrr9hc2#

你可以这样做,如果它是一个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);
x8diyxa7

x8diyxa73#

您需要将响应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)
        })
    };
  });

更多信息

waxmsbnn

waxmsbnn4#

我认为您可能在catch()中错误地使用了error变量。
Axios传递一个错误对象,该对象具有response属性,您将在该属性中查找errormessage
https://github.com/axios/axios#handling-errors
另一方面,如果您可以捕获服务器端的错误,您可以尝试将Content-type标头设置为text/plain

tvz2xvvm

tvz2xvvm5#

您可以执行以下操作

axios.post("URL", data, {
            validateStatus: (s) => s <= 500,
            responseType: 'blob',
            headers: {
                'Content-Type': 'application/json',
                'Accept': 'application/pdf'
            }
        })
    .then(async (response) => {
        if (response.status !== 200) {
            // error handling
            const error = JSON.parse(await response.data.text());
            console.log('error: ', error);
            alert(error.message);
        } else {
            console.log('res', response)
            const url = window.URL.createObjectURL(new Blob([response.data]));
            const link = document.createElement('a');
            link.href = url;
            link.setAttribute('download', 'file.pdf'); //or any other extension
            document.body.appendChild(link);
            link.click();
        }
    })
kx1ctssn

kx1ctssn6#

您可以全局转换blob响应:

$axios.onError(async ({request, response}) => {
  const status = response.status

  let data = response.data

  if (request.responseType === 'blob' && data instanceof Blob && data.type) {
    const text = await data.text()

    data = data.type.toLowerCase().includes('json') ? JSON.parse(text) : text
  }

  throw {status, data} // error model
})

相关问题