Home > Enterprise >  React render PDF file inside component based on API response
React render PDF file inside component based on API response

Time:02-21

I have an APIs which returns File(byte[], "application/pdf") | byte[] from server.

In the frontend part, I create a request and can save this file like a pdf file to a computer, but I need to store this file(State or some other way) and render inside react component like PDF file, it's can be put on iframe or some another way(for me it's doesn't matter, just need render inside component after getting the file from API).

 const instance = axios.create({
  baseURL: process.env.REACT_APP_API_ROOT,
  headers: {
    "Content-Type": "application/json",
  },
});

    function getPdfByFileName(fileName: string): any {
  return instance.get(`pdfs/${fileName}`);
}

function getPdfAsBlobByFileName(fileName: string): any {
  return instance.get(`pdfs/${fileName}/array`);
}

 useEffect(() => {
      getPdfByFileName("fileName")
        .then((response: AxiosResponse) => {
          // const file = new Blob([response.data], { type: "application/pdf" }); // For  API which returns blob
          setPdf(response.data); // Need store file and correct render like PDF
        })
        .catch((err: AxiosError) => {
         // process err
        });
    }
  }, []);

     return (
    <div>
      <iframe title="pdf" width="100%" height="600px" srcDoc={pdf}></iframe>
    </div>
  );

The result: Inside component I render the data but it's no PDF

I'm tryed:

  1. use "Content-Type": "application/pdf" inside these requests.
  2. Put the URL to file inside Iframe src attribute(it's works fine for Anonymous but we have Bearer and need to secure the data).
  3. Generate URL from blob API response and put to Iframe(not works).
  4. Different pdf viewers, they work fine with physical PDF files based on the path to file but don't work in my case.

Thanks for any help.

CodePudding user response:

For me the problem is on the axios, the response is not correct, I'm just switched to using fetch method and then this case start work correct for me, the same with axios does not work for me

    const request = new Request(`URL_TO_API`,
            {
              method: "GET",
              headers: {
                Authorization: `Bearer ${accessToken}`,
              },
              mode: "cors",
              cache: "default",
            }
          );
    
          fetch(request)
            .then((response) => response.blob())
            .then((blob) => {              
              const file = window.URL.createObjectURL(blob);
              const iframe = document.querySelector("iframe");
              if (iframe?.src) iframe.src = file;
            })
            .catch((err: AxiosError) => {
              // process error
            });
return (        
    <div>
      <iframe src="" width="100%" height="100%"></iframe>
    </div>
  );
  • Related