Javascript 如何在实现文件下载时避免粘性会话?

Javascript 如何在实现文件下载时避免粘性会话?,javascript,ajax,download,stateless,sticky-session,Javascript,Ajax,Download,Stateless,Sticky Session,这是一项任务——需要根据来自UI端(JavaScript)的一些数据生成一个文件。模式非常简单: UI向服务器发出异步POST HTTP请求,并提供一些JSON数据: $.ajax({ url: '/reports', type: "POST", data: JSON.stringify({...}), success: function (uuid) { wi

这是一项任务——需要根据来自UI端(JavaScript)的一些数据生成一个文件。模式非常简单:

  • UI向服务器发出异步POST HTTP请求,并提供一些JSON数据:

        $.ajax({
            url: '/reports',
            type: "POST",
            data: JSON.stringify({...}),
            success: function (uuid) {                    
                window.location = "/reports/" + uuid;
            }                
        });
    
  • 服务器接收请求,生成文件,将其放在文件系统中,并返回唯一ID:

    @RequestMapping(value = "/reports", method = RequestMethod.POST)
    public String generateReport(ReqData data) throws IOException {
      final String fileUuid = UUID.randomUUID();
      ...
      //generate a report and return filename
      ...
      return fileUuid;
    }
    
  • UI端获取生成的文件的唯一id并请求它:

    success: function (uuid) {                    
      window.location = "/reports/" + uuid;
    }  
    
  • 服务器输出请求的文件:

      @RequestMapping(value = "/reports/{uuid}", method = RequestMethod.GET)
      public ResponseEntity<InputStreamResource> downloadReport(@PathVariable("uuid") String fileUuid) throws IOException {
    
        final String resultFileName = fileUuid + ".txt";
        final Path resultFile = Paths.get(resultFileName);
    
        return ResponseEntity
                .ok()
                .header("Content-Disposition", "attachment; filename=\"" + resultFileName + "\"")
                .contentLength(Files.size(resultFile))
                .contentType(MediaType.parseMediaType("text/plain"))
                .body(new InputStreamResource(Files.newInputStream(resultFile)));
    } 
    
    @RequestMapping(value=“/reports/{uuid}”,method=RequestMethod.GET)
    public ResponseEntity downloadReport(@PathVariable(“uuid”)字符串fileUuid)引发IOException{
    最终字符串resultFileName=fileUuid+“.txt”;
    最终路径resultFile=Path.get(resultFileName);
    返回响应性
    .ok()
    .header(“内容处置”、“附件;文件名=\”“+resultFileName+”\“”)
    .contentLength(文件.size(结果文件))
    .contentType(MediaType.parseMediaType(“文本/普通”))
    .body(新的InputStreamResource(Files.newInputStream(resultFile));
    } 
    
  • 当我们用多个服务器来考虑这个模式时,问题就开始了。如果我们有两个实例服务器A服务器B并且前面有一个负载平衡器,那么我们需要确保上面提到的两个请求都转到同一个服务器。因此,需要粘性会话。为指定为like的服务器提供绝对路径不是一个好的选择,因为我们希望使所有服务器都无法从外部世界访问


    那么,有哪些选项可以实现下载生成的文件以及避免粘性会话呢?

    有几种方法可以实现解决方案。。尽管会话粘性在负载平衡器上启动并配置

    方法1: --使NFS空间可用,并将其装载到所有应用程序服务器上,然后在该位置生成报告。一旦挂载,可以从任何服务器提供相同的文件

    方法2:在其中一台服务器上实现一个本地文件存储库,并在生成报告时通过ftp协议将文件推送到存储库,这种方法可能会对性能产生一些影响,这将是通过ftp存储和检索文件的开销

    方法3:将报告存储在数据库中,并通过数据库从任何服务器检索报告


    方法4:为什么不在生成报告时将报告发送给客户机,为什么不在第一次调用时实现文件的交付呢。无论如何,在javascript中,您似乎在生成文件后接收响应时设置window.location。

    方法4:不可能使用ajax在浏览器中触发保存对话框-这就是为什么有两个ajax调用