在 Javascript 中,如何在窗口位置重定向 Ajax 响应

2024-03-22

我目前有以下内容working一段代码(角度但适用于任何 JS 框架):

var url = '/endpoint/to/my/file';

$http({
  method: 'GET',
  url: url
})
.success(function(jdata) {
  window.location = url;
})
.error(function(je){
  // display errors on page
});

上面的调用是在表单完成并且用户单击“提交”之后调用的(实际情况比这更复杂一些,但是是相同的想法)。我异步执行表单检查,因此无需重新加载页面。

如果请求成功,则返回一个二进制文件(pdf 文件),如果不成功,则请求返回 400 BadRequest,其中包含 JS 格式的错误。所以我要做的是,如果成功,我会重定向到相同的 url 以获取 PDF,否则我会获取 JSON 错误对象并对其执行某些操作。

如果请求成功,如何避免发出两次请求?

  • 注1:在后端,我只想保留一条可以完成所有操作的路由,检查+返回PDF
  • 注2:在我看来,目前的情况非常整洁,因为我有一个异步表单检查,如果成功,文件会直接在浏览器中下载,因为我有"CONTENT-DISPOSITION" -> "attachment"在成功响应的 HTTP 标头中

更新:根据 Emile 的要求,有关架构的其他信息: 在我的用例中,我有一个端点来检查输入(和其他外部要求)。出于安全原因,如果不满足所有要求,我就无法输出 PDF,因此我必须在交付文件之前进行检查(文件是自动生成的)。因此,拥有两个端点只是多余的,并且会增加一些不必要的复杂性。

在写作时,我认为另一种解决方案可能是在进行检查时在端点上传递一个参数,这样如果成功,它会停止并且不生成 PDF,然后重定向到没有标志的同一端点,该标记将输出 PDF 。 所以我检查了两次,但只加载(并生成 - 这是资源密集型的)文件一次,而且我只有一个端点......

这是改编后的代码:

var url = '/endpoint/to/my/file';

$http({
  method: 'GET',
  url: url+'?check'
})
.success(function(jdata) {
  window.location = url;
})
.error(function(je){
  // display errors on page
});

在后端(我使用 Play 框架/Scala)

def myendpoint(onlyDoCheck: Boolean = false) = Action{implicit request =>
   myForm.bindFromRequest.fold(
     e => BadRequest(myErrors),
     v => if(onlyDoCheck) Ok(simpleOkResponse) else  Ok(doComputationgeneratefileandoutputfile)
   )
}

真正的交易

您能做的最好的事情就是拆分您的端点。

  1. 一是为了形式和方便出现错误而无需刷新。
  2. 然后,成功后,重定向到仅下载文件的另一个端点。

如果文件位于磁盘上并且不是自动生成的并且需要经过身份验证才能下载,您可以将文件隐藏在正常端点后面,进行检查,然后使用返回文件X-Accel-Redirect标头带有 nginx 或X-Sendfile使用阿帕奇。

The hack

免责声明:这更像是一种黑客行为,而不是最佳解决方案。正如提到的@Iceman https://stackoverflow.com/questions/38665947/in-javascript-how-can-i-redirect-an-ajax-response-in-window-location/38666075?noredirect=1#comment64713949_38665947、Safari、IE、Safari-iOS、Opera-mini 和一些此类浏览器不支持此特定规范。

在服务器端端点中,如果文件可用且没有错误,则可以将标头设置为文件的内容类型(例如'application/pdf')这样下载就会自动开始。

如果有错误,不要设置 header,并返回错误的 json 通过 javascript 通知用户。

由于我们不知道后面是什么,这里有一个 python (Django) 示例:

response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename=your_filename.pdf'
response.write(repport.printReport(participantId))
return response

您可以在 ajax 成功回调中处理响应:

$.ajax({
    url: 'endpoint.php',
    success: function(data) {
        var blob = new Blob([data]);
        var link = document.createElement('a');
        link.href = window.URL.createObjectURL(blob);
        link.download = "filename.pdf";
        link.click();
    }
});

您也可以尝试jQuery 文件下载 https://github.com/johnculviner/jquery.fileDownload这个里面提到的插件answer https://stackoverflow.com/a/9970672/1218980.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Javascript 中,如何在窗口位置重定向 Ajax 响应 的相关文章

随机推荐