When I call send_data
at the end of a controller method to export an Excel file (using Axlsx), nothing happens IF the controller method was called using a POST. If the same controller method was called using a GET, send_data
works perfectly fine. In both scenarios, the Excel file is slightly different (the POST sends data that determines how the data is displayed in Excel), but I have verified that excel_file
is set up correctly when using POST. When calling the POST endpoint externally using Postman, the correct Excel file is downloaded. However, when clicking on the link in the browser that makes this POST request, send_data
seems to do nothing. The controller method has two lines of code:
excel_file = excel_util.export(params[:myPostParams]
send_data(excel_file.to_stream.read, type: "application/xlsx", filename: "MyExcelWorksheet.xlsx")
More information about my POST call:
I am calling the POST from an element on my view using JQuery ($.post method). Like I mentioned above, this seems to work perfectly fine because the POST call goes through passing the correct info in its body as excel_file
is built correctly.
Examining the Network in chrome's Developer Tools, using POST creates an 'export' action and a 'results' action. export
is the name of the controller method that handles the POST and GET. Here is the info (only included relevant info, the host/origin/referrer links are all fine).
'export' info:
Request URL: http://localhost:3000/<myappname>/export
Request Method: POST
Response Headers:
Content-Disposition:attachment; filename="MyExcelWorksheet.xlsx"
Content-Length:7648
Content-Transfer-Encoding:binary
Content-Type:application/xlsx
X-Content-Type-Options:nosniff
X-Frame-Options:SAMEORIGIN
X-Miniprofiler-Ids:["i6c3..."]
Request Headers:
Accept:*/*
Accept-Encoding:gzip, deflate, br
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:1803
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With:XMLHttpRequest
Form Data:
<the data I send in the body of my POST>
'results' info:
Request URL: http://localhost:3000/mini-profiler-resources/results
Request Method: POST
Response Headers:
Content-Type:application/json
Request Headers:
Accept:application/json, text/javascript, */*; q=0.01
Accept-Encoding:gzip, deflate, br
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:64
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With:XMLHttpRequest
Form Data:
id: <i6c3... < same as the X-Miniprofiler-Id shown above >
popup: 1
Is there an issue with rails letting POST requests respond with attachment downloads in the browser? This works when calling API externally, but not when using it in the browser.
This was indeed an issue with making a POST call with Ajax, not necessarily an issue with
send_data
. Here is a great workaround for making a POST call in Javascript and handling the call in Rails:https://gist.github.com/DavidMah/3533415
This worked for me, and I hope this awesome link gets more visibility.