在Javascript中如何在窗口位置重定向Ajax响应 [英] In Javascript how can I redirect an Ajax response in window location

查看:61
本文介绍了在Javascript中如何在窗口位置重定向Ajax响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前有以下工作代码片段(有角度但适用于任何JS框架):

I currently have the following working piece of code (angular but applies to any JS framework):

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

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

在表单完成并且用户点击提交(真实的)后调用上述内容情况比这更复杂,但它是相同的想法)。我异步进行表单检查,因此没有页面重新加载。

The above is called after a form was completed and the user has clicked on "submit" (the real situation is a bit more complex than this but it is the same idea). I do the form check asynchronously, so there's no page reload.

如果请求成功,则返回二进制文件(pdf文件),如果不成功,请求将返回400 BadRequest,并在JS中格式化错误。所以我做的是,如果成功,我会重定向到相同的URL以获得PDF,否则我会得到JSON错误对象并用它做一些事情。

If the request is successful, returns a binary (a pdf file), if not succesful, the request returns a 400 BadRequest with errors formatted in JS. So what I do is, if successful, I redirect to the same url to have the PDF otherwise I get the JSON error object and do something with it.

我怎么能如果请求成功,请不要发出两个请求?

How can I refrain from making two requests if the requests is successful?


  • 注意1:在后端方面我只想保留一条完成所有操作的路由,检查+返回PDF

  • 注意2:我认为目前的情况非常简洁,因为我有异步表单检查,如果成功,文件直接在浏览器中下载,因为我有内容 - 处置 - >成功响应的HTTP标头中的attachment

  • Note1: on the backend side I would like to keep only one route that does everything, check + return PDF
  • Note2: the current situation is pretty neat in my opinion, since I have an asynchronous form check and if successful the file downloads directly in the browser since I have "CONTENT-DISPOSITION" -> "attachment" in the HTTP header of the successful response

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

Update: additional information about the architecture as requested by Emile: In my use case I have one endpoint that checks inputs (and other external requirements). For security reasons I cannot output the PDF if all requirements are not satisfied so I have to do the check prior to delivering the file ( the file is automatically generated) anyway. So having two endpoints would just be redundant and add some unnecessary complexity.

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

While writing I think an alternative solution could be to pass an argument on the endpoint while doing the check, so that if successful, it stops and does not generate the PDF, and then redirect to the same endpoint without the flag which will output the PDF. So I do the check twice but only load (and generate - which is resource intensive) the file only once and I have only one endpoint...

以下是改编的代码:

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)

On the backend side (I use Play framework/Scala)

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


推荐答案

真正的交易



你能做的最好就是分割你的终点。

The real deal

The best you could do is split your endpoint.


  1. 一个表格和方便没有刷新的错误。

  2. 然后,成功后,重定向到只下载文件的另一个端点。

如果文件位于磁盘上且未自动生成并且需要进行身份验证以进行下载,则可以将文件隐藏在正常端点后面,执行检查并使用 X-返回文件带有nginx的Accel-Redirect 标头或使用apache的 X-Sendfile

If the file was on the disk and wasn't auto-generated and required to be authenticated to be downloaded, you could hide the file behind a normal endpoint, do the checks, and return the file using X-Accel-Redirect header with nginx or X-Sendfile using apache.

免责声明:这不是最好的解决方案。正如 @ Iceman ,Safari,IE,Safari-iOS,Opera-mini和一些此类浏览器不支持此特定规范。

Disclaimer: This is more of a hack than the best solution. As mention by @Iceman, Safari, IE, Safari-iOS, Opera-mini and some such browsers don't support this particular spec.

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

In your server-side endpoint, if the file is available without errors, you can set the header to the content-type of the file (like 'application/pdf') so the download will starts automatically.

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

If there are errors, don't set the header and return a json of the errors to inform the user through javascript.

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

Since we don't know what's behind, here's a python (Django) example:

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

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

You can handle the response in the ajax success callback:

$.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();
    }
});

你也可以试试答案中提到的rel =nofollow noreferrer> jQuery fileDownload 插件。

You could also try the jQuery fileDownload plugin mentioned in this answer.

这篇关于在Javascript中如何在窗口位置重定向Ajax响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆