English 中文(简体)
如何下载使用APICA号线路的下杰斯档案
原标题:How to download a file on Next.js using an API route

页: 1 我有三党服务,需要从国防军档案中取回。 这项服务需要一个我不想在客户方面暴露的APIC钥匙。

我的档案

/api/getPDFFile.js ...

  const options = {
    method:  GET ,
    encoding:  binary ,
    headers: {
       Subscription-Key : process.env.GUIDE_STAR_CHARITY_CHECK_API_PDF_KEY,
       Content-Type :  application/json ,
    },
    rejectUnauthorized: false,
  };

  const binaryStream = await fetch(
     https://apidata.guidestar.org/charitycheckpdf/v1/pdf/26-4775012 ,
    options
  );
  
  return res.status(200).send({body: { data: binaryStream}}); 


pages/getPDF.js

   <button type="button" onClick={() => {
  fetch( http://localhost:3000/api/guidestar/charitycheckpdf ,
    {
      method:  GET ,
      encoding:  binary ,
      responseType:  blob ,
    }).then(response => {
      if (response.status !== 200) {
        throw new Error( Sorry, I could not find that file. );
      }
      return response.blob();
    }).then(blob => {
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement( a );
      a.style.display =  none ;
      a.href = url;
      a.setAttribute( download ,  test.pdf );
      document.body.appendChild(a);
      a.click();
      window.URL.revokeObjectURL(url);
    })}}>Click to Download</button>

Clicking the button downloads a file, but when I open it I see the error message, "Failed to load PDF document."

最佳回答

您似乎正在使用。 因此,你可以这样做:

// /pages/api/getAPI.js

import stream from  stream ;
import { promisify } from  util ;
import fetch from  node-fetch ;

const pipeline = promisify(stream.pipeline);
const url =  https://w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf ;

const handler = async (req, res) => {
  const response = await fetch(url); // replace this with your API call & options
  if (!response.ok) throw new Error(`unexpected response ${response.statusText}`);

  res.setHeader( Content-Type ,  application/pdf );
  res.setHeader( Content-Disposition ,  attachment; filename=dummy.pdf );
  await pipeline(response.body, res);
};

export default handler;

Then from client:

// /pages/index.js

const IndexPage = () => <a href="/api/getPDF">Download PDF</a>;
export default IndexPage;

CodeSand Box 链接 (开放在新表格中投放,看其工作情况。)

参考资料:

PS:我认为,在这种情况下没有必要处理许多错误。 如果你希望向你们的用户提供更多信息,你能够这样做。 但是,这部法典也只会奏效。 如果出现错误,文档下载将无法显示“Server Error”。 此外,我看不出需要创建<条码>blob。 URL 首先。 你可以直截了当地下载该版本,因为原封不动。


更早的request

import request from  request ;
const url =  https://w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf ;
export default (_, res) => { request.get(url).pipe(res); };
问题回答

@brc-dd挽救了我对这个问题的看法。 我必须补充的内容之一是动态生成的联系要素(见varLink in the Code”),一旦我们从APIC获得档案数据,就将其点击。 这对于不断下载非常重要(我没有事先这样做)。

我的网页代码建立了下载档案的链接:

// the fileProps variable used below looks like {"file_name":"test.png", "file_type":"image/png", "file_size": 748833}
import Button from  react-bootstrap/Button 
import { toast } from  react-toastify ;

const DataGridCell = ({ filename, filetype, filesize }) => {
    const [objFileState, setFileDownload] = useState({})

    // handle POST request here
    useEffect(() => {
        async function retrieveFileBlob() {
            try {
                const ftch = await fetch( // this will request the file information for the download (whether an image, PDF, etc.)
                    `/api/request-file`,
                    {
                        method: "POST",
                        headers: {
                            "Content-type": "application/json"
                        },
                        body: JSON.stringify(objFileState)
                    },
                )
                const fileBlob = await ftch.blob()

                // this works and prompts for download
                var link = document.createElement( a )  // once we have the file buffer BLOB from the post request we simply need to send a GET request to retrieve the file data
                link.href = window.URL.createObjectURL(fileBlob)
                link.download = objFileState.strFileName
                link.click()
                link.remove();  //afterwards we remove the element  
            } catch (e) {
                console.log({ "message": e, status: 400 })  // handle error
            }
        }

        if (objFileState !== {} && objFileState.strFileId) retrieveFileBlob()   // request the file from our file server

    }, [objFileState])

    // NOTE: it is important that the objFile is properly formatted otherwise the useEffect will just start firing off without warning
    const objFile = {
        "objFileProps": { "file_name": filename, "file_type": filetype, "file_size": filesize }
    }
    return <Button onClick={() => {toast("File download started"); setFileDownload(objFile) }} className="btn btn-primary m-2">Download {filename}</Button>

}

我的当地未来司法协会终端点(/api/qualtrics/retrieve-file)认为,链接要求:

/**
 * @abstract This API endpoint requests an uploaded file from a Qualtrics response
 * (see Qualtrics API reference for more info: 
https://api.qualtrics.com/guides/reference/singleResponses.json/paths/~1surveys~1%7BsurveyId%7D~1responses~1%7BresponseId%7D~1uploaded-files~1%7BfileId%7D/get)

 * For this API endpoint the parameters we will be:
 * Param 0 = Survey ID
 * Param 1 = Response ID
 * Param 2 = File ID
 * Param 3 = Header object (properties of the file needed to return the file to the client)
 *
 */
// This is a protected API route
import { getSession } from  next-auth/client 

export default async function API(req, res) {
    // parse the API query
    const { params } = await req.query  // NOTE: we must await the assignment of params from the request query
    const session = await getSession({ req })
    const strSurveyId = await params[0]
    const strResponseId = await params[1]
    const strFileId = await params[2]
    const objFileProps = JSON.parse(decodeURIComponent(await params[3]))    // file properties
    // this if condition simply checks that a user is logged into the app in order to get data from this API
    if (session) {
        // ****** IMPORTANT: wrap your fetch to Qualtrics in a try statement to help prevent errors of headers already set **************
        try {
            const response = await fetch(
                `${process.env.QUALTRICS_SERVER_URL}/API/v3/surveys/${strSurveyId}/responses/${strResponseId}/uploaded-files/${strFileId}`,
                {
                    method: "get",
                    headers: {
                        "X-API-TOKEN": process.env.QUALTRICS_API_TOKEN
                    }
                }
            );

            // get the file information from the external API
            const resBlob = await response.blob();
            const resBufferArray = await resBlob.arrayBuffer();
            const resBuffer = Buffer.from(resBufferArray);
            if (!response.ok) throw new Error(`unexpected response ${response.statusText}`);

            // write the file to the response (should prompt user to download or open the file)
            res.setHeader( Content-Type , objFileProps.file_type);
            res.setHeader( Content-Length , objFileProps.file_size);
            res.setHeader( Content-Disposition , `attachment; filename=${objFileProps.file_name}`);
            res.write(resBuffer,  binary );
            res.end();
        } catch (error) {
            return res.send({ error: `You made an invalid request to download a file ${error}`, status: 400 })
        }

    } else {
        return res.send({ error:  You must sign in to view the protected content on this page... , status: 401 })
    }
}




相关问题
How to upload and download file from a server using C#

I am developing a webpage in that the user can download their Resume for Edit. So I have a link to download the article. I use the following code for download. DataTable dt = user.getUserDetails(2); ...

Detecting PDF Download

I have recently added functionality for generating pdf reports to a web application. However the reports can be quite large and take some time to show the pdf download dialog. I want to show a spinner ...

Writing file to users giving sporadic error in IE

I have a very interesting issue with only specific IE implementations. I have an ASPX page that is used to write files down to the user, as part of the process the page uses the following code to ...

PHP - List of Excel files to download from Intranet Site?

I have a intranet site running PHP 5 that needs to list a folder containing only Excel files. Ideally the user needs to be able to input some search criteria (ie date) and the files would be filtered ...

Determine total size of SVN directory/trunk

Is there a way to count/calculate the total size of a svn directory if you were to checkout a revision? I have limited internet downloads so I need to know how big something is before I go and ...

Scala and html: download an image (*.jpg, etc) to Hard drive

I ve got a Scala program that downloads and parses html. I got the links to the image files form the html, Now I need to transfer those images to my hard drive. I m wondering what the best Scala ...

Downloading file with wxHTTP?

Im really stumped. Im using the wxHTTP class in wxWidgets to try and download two files. The first request succeeds but the second one fails when wxHTTP->GetInputStream is called. Between downloads, ...

热门标签