I want to download a file from the front end. The file is generated in the TestFlow.generateReport method.
My code runs until the end but it doesn't download anything. It just prints the data to the console.log.
What am I missing here?
My backend controller:
#RequestMapping(value = "/flow/generate-report" , method = RequestMethod.GET)
public #ResponseBody void generateFlowReport(#RequestParam("flowName") String flowName, HttpServletResponse response) {
InputStream resource = TestFlow.generateReport(flowName);
response.setContentType("application/force-download");
response.setHeader("Content-Disposition","attachment; filename=report-" + flowName + ".xlsx");
try {
IOUtils.copy(resource,response.getOutputStream());
response.flushBuffer();
resource.close();
} catch (IOException e) {
e.printStackTrace();
}
}
My frontend code:
$('.generateReport').click(function () {
var flowName = $(this).attr('name');
$.ajax({
url: '/flow/generate-report',
type: 'get',
data: {flowName: flowName},
success: function (data) {
console.log(data);
}
})
});
I get HTTP status 200
HTTP/1.1 200
Content-Disposition: attachment; filename=report-tellerFlow.xlsx
Content-Type: application/xlsx
Transfer-Encoding: chunked
Content-Type: application/force-download header might not always work because some browsers/web clients might not support the attachment download.
Try changing to Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet which is the correct XLSX type and then check the documentation for your browser/web client. As per this answer using Ajax to download a file might not won't work in your web client.
I'm not sure that an XHR request can trigger a download dialog on the browser. You might want to spawn a new window instead with the download URL - the browser should detect the content disposition and handle the download accordingly.
If you still want to do it with XHR, you need to use Blobs instead - JavaScript blob filename without link
Related
I am creating a file on server in a request from client-side. Now, I want to send that file in response to the AJAX response. Below is the JAVA code.
response.reset();
response.setContentType("application/pdf");
response.setHeader("Content-disposition", "attachment; filename=\"Portfolio.pdf\"");
OutputStream output;
try {
output = response.getOutputStream();
output.write(Util.readFileInBytes("/Portfolio.pdf"));
output.close();
} catch (IOException e) {
e.printStackTrace();
}
Now, how to show a "Save As" dialog to user for saving the file. Thanks in advance for the help.The javascript code is as below :
$.ajax({
url : "export",
dataType : 'text',
contentType : 'application/pdf',
success: function() { //code to display "Save As" dialog box to user.}});
Also see this discussion stackoverflow.com/questions/833068/how-to-force-save-as-dialog-box-in-firefox-besides-changing-headers.
You can encode file in base64 string, send it to client and then assign the value to location.href and save dialog will be shown to user.
But it won't work in IE. Don't know what are your requirements.
Hi Here my Sql Table
I want to download those files using java script . I get Record from "ID" to my java script . I want to download those files, how can i do that
here is the my script get file by ID
function DownloadFile(e) {
$.ajax({
dataType: 'JSON',
url: '/api/FileAttachment/GetFileByID',
async: false,
data: { id: e },
success: function (data) {
downloadPDFfile(data);
}
});
}
function downloadPDFfile(a) {
// I want write download code here
}
If you want to download a file from server, at first create a url request like this:
function downloadPDFfile(param) {
var downloadUrl = http://www.yourhost.com/download?id=param
window.open(downloadUrl);
}
At your server, write code to receive this request, get requested param(s), read your binary data from db then response this data to client as a stream and the browser will do it's job.
Dont't forget to specify HTTP response header fields. For example:
Content-Type: text/html /* MIME type */
Content-Disposition: attachment; filename="fname.ext" /* Using 'attachment' option to raise a "File Download" dialogue box */
I have a web application running on Spring MVC using RESTful web services. I'm trying to send a JSON to those web services from an HTML/Javascript file. Here's the Javascript:
$.ajax
(
{
type: "post",
data: JSON.stringify(data),
contentType : "application/json",
dataType: "json",
url: "http://localhost/proj/service",
success: function(data)
{
callback(data);
}
}
);
And the mapping in Spring MVC:
#RequestMapping(value = "/proj/service/", method = RequestMethod.POST)
public ModelAndView procRequest(#RequestBody String paramsJson, HttpServletResponse resp, WebRequest request_p){
resp.setStatus(HttpStatus.CREATED.value());
resp.setHeader("Location", request_p.getContextPath() + "/proj/service");
resp.addHeader("Access-Control-Allow-Origin", "*");
//Code
}
For some reason when I delete the contentType key from the ajax request it goes through, but of course it is in an incorrect format since I expect the Javascript to send me a JSON string. But for some reason if I leave the contentType key I get the following error:
XMLHttpRequest cannot load http://localhost:8080/proj/service/. Origin http://localhost is not allowed by Access-Control-Allow-Origin.
I don't know what could possibly be causing this error since the appropiate header is there.
Thanks.
The Content-Type header triggers a CORS preflight request. You need to modify your handler to respond to an OPTIONS request with the following headers:
resp.addHeader("Access-Control-Allow-Origin", "*");
resp.addHeader("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE");
resp.addHeader("Access-Control-Allow-Headers", "Content-Type");
This should send the appropriate response to the preflight request, after which the browser will issue the actual request. You can learn more about preflight requests here: http://www.html5rocks.com/en/tutorials/cors/
I do it like this:
#RequestMapping("/listActions")
public #ResponseBody List<Action> list(HttpServletRequest request, HttpServletResponse response) {
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE");
response.addHeader("Access-Control-Allow-Headers", "Content-Type");
List<Action> actions = new ArrayList<Action>();
actions.add(new Action(1, "Do something fantastic"));
actions.add(new Action(2, "Save the world"));
actions.add(new Action(3, "Buy beer"));
actions.add(new Action(4, "Butcher a hog"));
return actions;
}
I have a jetty server running which responds to get requests. If I make the request using a browser:
localhost:8080/sp or 127.0.0.1:8080/sp
I get the correct data back.
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("application/json");
response.setStatus(HttpServletResponse.SC_OK);
PrintWriter out = response.getWriter();
out.println("{foobar: true"});
response.flushBuffer();
out.flush();
out.close();
}
but when I try to access the same url using JS the response body is empty.
I've tried serving the webpage using both the OS X webserver(port 80) and python SimpleHTTPServer (port 3000).
In both cases the response is empty.
<h1>Single Test Page</h1>
<script>
var httpReq = null;
var url = "http://127.0.0.1:8080/sp";
window.onload = function(){
var myRequest = new XMLHttpRequest();
myRequest.open('get', url);
myRequest.onreadystatechange = function(){
if ((myRequest.readyState == 4) || (myRequest.status == 200)){
alert(myRequest.responseText);
}
}
myRequest.send(null);
}
</script>
Could it be an issue with xss attack prevention?
How can I change my setup to use JS to talk to my servlet?
Is there any other way I can make the HTTP get request from JS?
I even added an entry into my /etc/hosts file:
127.0.0.1 foo.com
and changed the JS url to no avail.
Yes, the problem is that it's a cross domain request.
2 possible solutions :
use JSONP
set CORS headers so that the browser knows it may embed your servlet answer
Both are easy but the second one has the advantage that you just have to set the headers in the servlet code. For example :
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Request-Method", "GET");
Another thing : be careful to open your html file in http:// and not file://.
I have been trying to call a .NET method (both as asmx file and as a normal aspx file) from another domain through JQuery and I just can't get the job done in every browser. At the moment it works fine in Firefox but not in IE.
function save() {
if (jQuery.browser.msie && window.XDomainRequest) {
// Use XDR
var params = "{'height':" + 10 + ",'width':" + 10 + ",'pos':'" + 10 + "'}";
var xdr = new XDomainRequest();
xdr.onerror = alert_error;
xdr.ontimeout = alert_timeout;
xdr.onprogress = alert_progress;
xdr.onload = alert_loaded;
xdr.timeout = 10000;
xdr.open("post", 'http://domain/reciever.asmx/setdata');
//Tried as webservice and as a normal aspx page
//xdr.open("post", 'http://domain/default.aspx');
xdr.send(params);
}
else {
var params = "pos=" + positions + "&width=" + screenWidth + "&height=" + screenHeight;
var myAjax = new jQuery.ajax(
"http://domain/default.aspx",
{
type: 'post',
cache: false,
crossDomain: true,
data: params
});
}
}
On the server end the web.config has:
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
And the webservice
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string setdata(int width, int height, string pos)
The aspx page returns:
Response.Clear();
Response.ContentType = "text/plain";
Response.AddHeader("Access-Control-Allow-Origin", "*");
Response.End();
Fiddler says:
Fiddler has detected a protocol violation in session #2565.
Content-Length mismatch: Request Header indicated 38 bytes, but client sent 0 bytes. So i would believe it to be the "Access-Control-Allow-Origin" but this I have set (to my knowledge at least).
Can someone help me understand what I am doing wrong.
Some browsers do not allow cross-domain Ajax calls (a call using the XmlHttpRequest object) for some security reasons.
But the solution is instead of ajax calls use JSONP calls. The JSONP avoids this by making a request suitable for a script file. By using JSONP the following things happen to make cross-domain request possible,
1.Instead of accessing the XHR object, the browser first creates a new script tag to inject into the HTML DOM.
2.The script tag's URL is set to the URL you're looking to get/post(using HTTP GET) data to.
3.The script tag is injected into the page, causing...
4.The request is sent to the server, even if it's cross-domain
5.The server returns the data in the form of a JavaScript function call
6.The browser receives the data and executes the function call
See the urls below to get the implementation details,
http://www.codeproject.com/Articles/78757/Making-Cross-Domain-jQuery-AJAX-Calls.aspx
http://usejquery.com/posts/9/the-jquery-cross-domain-ajax-guide
Hope this definitely helps you...