2016-11-20 61 views
1

我有一個後端API,只要我們調用它,基本上會下載一個模板。 我在我的html頁面上提供了一個href,因此無論何時有人點擊該href,它都會調用後端API,並且應該下載該文件。如何使用反應保存從服務器下載的文件?

但該文件沒有得到下載。

我正在使用React。如果我只是從我的瀏覽器中點擊後端,文件會被下載,但如果我從反應中調用它,則不會。

任何線索?

REACT CODE:

const config = require('config'); 
 
var aws4 = require('aws4'); 
 
const Promise = require('axios'); 
 

 
const requestHelper = { 
 
    appendHeaders(request){ 
 
    request.headers = request.headers || {}; 
 
    if(request.headers["Content-Type"]){ 
 
     return 
 
    } 
 
    request.headers["Content-Type"] = "application/json"; 
 
    }, 
 
    externalApi(request, serverResult){ 
 
    if(!request.method){ 
 
     request.method='POST'; 
 
    } 
 
    request.path = request.url 
 
    this.appendHeaders(request) 
 
    console.log('request',request) 
 
    return Promise(request) 
 
    .then((apiResponse) => { 
 
     if (apiResponse.data.errors) { 
 
     var error = apiResponse.data.errors; 
 
     console.log('api error response: ', error); 
 
     serverResult.status(400).json({ error }) 
 
     } else { 
 
     console.log('api response: ', apiResponse.data); 
 
     serverResult.status(200).json(apiResponse.data); 
 
     } 
 
    }).catch((error) => { 
 
     console.log('api error response: ', error); 
 
     serverResult.status(400).json({ error }); 
 
    }); 
 
    }, 
 

 
    getDownloadResponse(request, serverResult){ 
 
    debugger; 
 
    request.path = request.url 
 
    this.appendHeaders(request) 
 
    console.log(request); 
 
    return Promise(request) 
 
    .then((apiResponse) => { 
 
     if (apiResponse.data.errors) { 
 
     var error = apiResponse.data.errors; 
 
     console.log('api error response: ', error); 
 
     serverResult.status(400).json({ error }) 
 
     } else { 
 
     serverResult.status(200); 
 
     console.log('api response status: '+200); 
 
     } 
 
    }).catch((error) => { 
 
     console.log('api error response: ', error); 
 
     serverResult.status(400).json({ error }); 
 
    }); 
 
    } 
 
}; 
 

 
module.exports = requestHelper;

BACKEND API代碼:

@RequestMapping(value = GlobalConstants.DOWNLOAD_FILE, method = RequestMethod.GET) 
public void downloadTemplate(HttpServletRequest hRequest, HttpServletResponse response) throws Exception { 

    InputStream in = null; 
    OutputStream out = null; 
    try { 
     if (!StringUtils.isEmpty(sampleFile)) { 
      File file = new File(sampleFile); 
      in = finderService.downloadFile(sampleFile); 
      if (in != null) { 
       MimetypesFileTypeMap mimetypesFileTypeMap = new MimetypesFileTypeMap(); 
       response.setContentType(mimetypesFileTypeMap.getContentType(file)); 
       String headerKey = "Content-Disposition"; 
       String headerValue = String.format("attachment; filename=\"%s\"", file.getName()); 
       response.setHeader(headerKey, headerValue); 

       out = response.getOutputStream(); 
       byte[] buffer = new byte[4096]; 
       int length; 
       while ((length = in.read(buffer)) > 0) { 
        out.write(buffer, 0, length); 
       } 
      } 
     } else { 
     response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); 
     } 
     logger.error("Internal Server error"); //Add logs for server error here also 

    } catch (Throwable th) { 
     response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); 
     logger.error(th); 
     return; 
    } finally { 
     if (in != null) { 
      in.close(); 
     } 
     if (out != null) { 
      out.flush(); 
     } 
    } 
} 
+1

任何錯誤控制檯?沒有足夠的細節來回答你。 –

+0

沒有錯誤。我打到API,但文件沒有得到下載。我認爲服務器端渲染將是必需的? –

+0

然後添加一些代碼也許? –

回答

7

中的JS GET的要求是不一樣的在訪問一個網址你瀏覽器。你需要通過指定的URL,例如像這樣直接調用客戶端下載:

download() { 
    // fake server request, getting the file url as response 
    setTimeout(() => { 
    const response = { 
     file: 'http://releases.ubuntu.com/12.04.5/ubuntu-12.04.5-alternate-amd64.iso', 
    }; 
    // server sent the url to the file! 
    // now, let's download: 
    window.open(response.file); 
    // you could also do: 
    // window.location.href = response.file; 
    }, 100); 
} 

這爲a working example on JSBin

注意如果要下載瀏覽器可以顯示的文件(如JSON,圖像,視頻),它們將顯示在新選項卡中。如果您希望直接下載這些類型的文件,則需要使用一些解決方法,例如使用blob。這裏有a few examples of this

+0

太好了。有效。非常感謝。需要幫助(我是前端新手)。如何處理在React中拒絕的連接?說後端是否關閉。 –

+0

在你的Promise中你有'.catch((error))'函數,你可以處理向用戶顯示的錯誤信息。你也可以設置一個[axios的超時時間](https://github.com/mzabriskie/axios#axioscreateconfig),如果在那段時間沒有得到數據,它將會拋出一個錯誤。 –

+0

爲什麼'setTimeout'? –

2

可以使用陣營「一」元素與hrefdownload道具:

<a href={getFile.url} 
    download={getFile.saveAsFileName}> 
</a> 
相關問題