Handling PDF result data from ajax success - javascript

I wondered if anyone could suggest an alternative approach to the following work around.
I have a web application that makes an http request for a PDF. The PDF can take more than the default timeout for a request to be created server side, so to better control this, I have used ajax, where as previously just window.open had been used.
However, because of how the PDF is prepared, the request to create it, also returns it. I couldnt work out a way to handle the binary PDF data returned so I simply rellied on the browsers cache to store the data. Then simply requested against the same url again, but using window.open.
The code for this is as follows..
function loadPdf(url, timeout){
$.ajax({
url: url,
success: function(data){
window.open(url);
},
error: function(error, status){
window.alert("Problem retrieving PDF.\nThe error status is: " + status);
},
timeout: timeout,
dataType: "application/pdf"
});
}
Really what I would like to do is handle the success data in a way that asks the user to open/save the PDF. I dont really like to use window.open in this way, especially as a repeat call like this.

Really what I would like to do is handle the success data in a way
that asks the user to open/save the PDF
That's impossible. You should not use AJAX to download files. You can't do anything useful with the byte array that you retrieved in the success callback. You can't directly save it on the client computer (for obvious reasons) and you can't prompt the user with the Save dialog neither.
You don't need to use window.open either. You could simply provide a link to the file:
download pdf
and then on the server specify the: Content-Disposition: attachment; filename="test.pdf" custom HTTP header to show the save dialog allowing the user to specify a location on his computer to store the file.

Would the jquery.fileDownload plugin do what you need?

Related

convert jquery ajax method to javascript

purpose:When we clicking on a link it opens a new window going to gotopage2.aspx.Please help in understanding the code. what does the data parameter in function() contain? the ajax request settings say that request is synchronous and if success run the function. How is the url parameter being used in this context? How can i write the below function in pure javascript without using jquery/ajax settings?
$.ajax({
url: "page1.aspx?Q=userSess1",
async: false,
success: function(data) {
if(data.substring(0, 1)=="1") {
if(mywindow){
mywindow.focus();
}
else{
mywindow=open('gotopage2.aspx','newwindow home page');
}
}
else {
alert("fail");
}
}
});
If all you want is to open a particular URL in a new window, you don't need any fancy JS. All you need is a hyperlink, with the target attribute set to _blank, like so:
CLick me!
AJAX is used to fetch information from the server and dynamically updating our page without refreshing the entire page and without opening a new window. For example, retrieving some JSON from a WEB API endpoint URL.
The url parameter in your ajax call is used to tell the browser where is should retrieve the data from. This is similar to typing "google.com" in your browser and pressing Enter. "Google.com" becomes the address from where the data is downloaded and displayed in your browser.
There are various alternatives to using $.ajax(). Most browsers nowadays have a function called fetch(), which essentially does the same as $.ajax(). Also, most browsers should support the XMLHttpRequest object which does the same. There are also third party JS libraries that can do AJAX as well, like axios and superagent. But as mentioned, if all you want is to open a new Window with a particular page, an tag should suffice. Hope this helps.

Electron - download .zip file using ajax?

I'm trying to build an Electron-based app, mostly using code from my existing web app. The electron version connects to my server and often relies on that online content. I am using Ajax requests (using Jquery) handle things like the user logging on, and a php session is created, which is required to access most of the content.
I am now trying to get Javascript to automatically download a .zip file and save it to a location, without the user doing anything. I failed to do this using an Ajax request, so have tried to use the Node.js 'request' module. Then however, it wouldn't download the file because it was not authorised (because the request creates a new session, different to the existing, logged-in one).
How can I get something like the following to work?
const fs = require("fs");
...
$.ajax({
url: "my-server/file.zip",
success: function (data) {
fs.writeFile("local-file.zip", data);
}
});
Note - I think it failed due to some issue with the way the downloaded data is encoded, but don't understand exactly what the problem was.
Alternatively, is it possible to use the existing ajax session in the request module, and download it that way?

How to send a request from JavaScript without base URL?

I'd like to send a request to a simple URL from my JavaScript, so that the base URL will NOT be added to the request URL. For example, the request should be sent to the following URL (without the base URL):
SAPEVENT:SOME_TEXT?2
I used the jQuery's $.ajax function in order to implement it, but without success.
Here is a JSFiddle for it:
http://jsfiddle.net/txb6tdjj/2/
The JS code:
function sendEvent(id) {
$.ajax("SAPEVENT:SOME_TEXT?" + id);
}
sendEvent(2);
I see the following error in the JS console:
XMLHttpRequest cannot load sapevent:SOME_TEXT?2. Cross origin requests
are only supported for HTTP. (jquery-2.1.0.js:8556)
I even set the parameter crossDomain: true, but it didn't help:
http://jsfiddle.net/auhx2v2v/3/
The JS code:
function sendEvent(id) {
$.ajax({
url: "SAPEVENT:SOME_TEXT?" + id,
crossDomain: true
});
}
sendEvent(2);
It ends up with the same error.
It works correct in the HTML like this:
http://jsfiddle.net/1f6npcn2/2/
The HTML code which works correctly:
<FORM action="SAPEVENT:PRESS_ME">
Click on me to send an event!
<INPUT TYPE="submit" VALUE="Press me to send an event!"/>
</FORM>
But I need to implement it in JavaScript, so that a request parameter can be set dynamically in the URL in JavaScript.
Do you know how to implement it in JS so that the request will be sent to the URL SAPEVENT:SOME_TEXT?2 without the base URL?
Additional information about used browsers: The error is shown only in Chrome. IE and Firefox do not show an error, but they also don't send the request.
Additional information for the SAP guys: I know there is a SAP Note 191908 which states that it's impossible, but a colleague has confirmed that he has successfully tested such functionality in an HTML page which used the same code as I copied above (see the HTML code above and http://jsfiddle.net/1f6npcn2/2/). So the SAP Note is wrong. I know how I can implement this functionality in HTML, but I don't know how I can implement it in JS. That's the problem.
I have no experience of working with SAP but I think you are missing a crucial part here.
In the samples you gave SAPEVENT:CLICK_ON_ME isn't a http url at all but rather it would invoke whatever handles the SAPEVENT-protocol on the local computer with the parameter CLICK_ON_ME. I'm guessing that you have some sort of client installed on your computer that does this for you (how do I create my own URL protocol? (e.g. so://...) contains some more information on how this is accomplished).
The reason your error-message talks about crossdomain-stuff is probably because it tried to interpret it as host:port.
So in other words, since this isn't a http url there isn't a webserver working on the other end so you can't do ajax-requests against it.
The SAPEVENT: stuff is not handled by any web server. The SAP GUI uses an embedded Internet Explorer and registers a custom protocol handler. There is no use in trying to use ajax techniques since you need to reach the container of the client, not the server. To reiterate: You do not want to "send a request" anywhere, you want to convince the browser that a certain local navigation event happened". SAP Note 191908 contains more information on that topic.
No idea about SAP Views, but to me this seems like a usual behaviour on webservers. I presume that SAPEVENT gets parsed by the server during the runtime to a more regular URI. Only the views get parsed, not the resources like CSS and JS, so the SAPEVENT placeholders in the JS file don't get parsed and the JS interpreter will not accept it as a valid URI. One of the common ways of solving this, is to create either a hidden form in the HTML or just a hidden input containing the server-generated values you are needing. For example
SAP View:
<input type="hidden" id="my_event_url" value="SAPEVENT:PRESS_ME">
JS:
function sendEvent(id) {
$.ajax({
url: $('#my_event_url').val() + '?' + id,
crossDomain: true
});
}
sendEvent(2);
I finally implemented it in JavaScript. Thanks go to this web page.
I modified the solution which was shown in this web page in order to add a link instead of a form in JavaScript.
This is the working solution in JS:
var targetUrl = "SAPEVENT:SOME_TEXT?2";
function sendSapEvent(targetUrl) {
var link = document.createElement("a");
link.setAttribute("style", "display:none;");
link.setAttribute("href", targetUrl);
// Move the click function to another variable
// so that it doesn't get overwritten.
link._click_function_ = link.click;
document.body.appendChild(link);
link._click_function_();
}
sendSapEvent(targetUrl);
You can find it also in this JSFiddle: http://jsfiddle.net/708r95p0/6/
It works! It sends a request to the URL sapevent:SOME_TEXT?2
I decided to use a link instead of a form element, bacause I couldn't pass the request parameter using a form.

How could my MVC JSON action be called with GET if my only use is with POST?

I have an ASP.NET MVC action that is returning JSON. The only place I am calling that action is from one page with this code:
$.ajax({
type: 'POST',
url: actionUrl,
dataType: 'json',
...
});
The page and this AJAX call are working fine from the user and testing perspective. However I found one error in the log saying:
This request has been blocked because sensitive information could be
disclosed to third party web sites when this is used in a GET request.
To allow GET requests, set JsonRequestBehavior to AllowGet.
and indicating my "actionUrl" in the SCRIPT_NAME server variable. The REQUEST_METHOD is GET and QUERY_STRING is empty. There is also a HTTP_REFERER server variable which indicates it is coming from the page with the above $.ajax() call, so it doesn't seem likely it's someone is accessing the JSON action manually.
The only thing I have come up with is that something strange might happen if the user hits the Back or Refresh buttons in the browser, but that doesn't seem right.
Is there any solid explanation of how that one GET request could have been generated?
I can only guess what probably happened. If someone is looking at the Network tab of the Developer Tools in their browser, they can see the file being called. If they right click the file and "Open in new tab", the page will be opened with a GET, and you will see the error message. Someone was probably testing and manually opened the link.
Probably $.ajax uses some get requests by default, use $.post() instead of it.
$.post( url, function( data ) {
$( ".result" ).html( data );
});

Retrieving response from remote server after uploading a file in iframe

I have a form that uploads a file in an firame to a remote server. As a result at the submission url server returns json data with the result of operation, which my iframe catches.
{'result': 'true' or 'false'}
Now I'd like to retrieve this json as the callback of my iframe. I know that I need jsonp to achieve this since it's a cross-site call. Here's my function with sample code from IBM' site :
function fileUploadFunction(){
var fileUploadForm = $('#file_upload_form');
fileUploadForm.attr('action', uploadURL);
fileUploadForm.submit();
$('#upload_target').load(function () {
alert("IFrame loaded");
$.getJSON(uploadUrl+"&callback=?", function(data) {
alert("Symbol: " + data.symbol + ", Price: " + data.price);
});
});
};
But here few problems arise. First - my uploadUrl is just "http://something/" . Do I need it to support calls with $callback= suffix ?
Secondly - server gives response only as a result to file upload. So I need to get the result that is stored in my iframe and not at the specified url. How to solve this ?
Here's the link. Notice hidden iframe inside the form. Result from server shows there. :
http://ntt.vipserv.org/artifact/
EDIT
I've previously tried :
$('#upload_target').load(function () {
var ret = frames['upload_target'].document.getElementsByTagName("body")[0].innerHTML;
var data = eval("("+ret+")");
});
But it raises 'permissions denied' error.
This is easily done with easyXDM and there is actually a blog post about this exact use case here.
In essence what it does is use cross-domain messaging to relay the response to the invoking document.
Update: Here is a link for this in action, the source can be found at github, the files are prefixed 'upload_'.
Sean's easyXDM recommendation is a great option (& should probably be marked as correct), but I wanted to suggest another light-weight solution that I haven't seen anyone use.
In cases where you're posting to a hidden iframe on another domain & just need a single response back (not two-way communcation), you could pass a message from the iframe to the parent using a busted url. Here's an example:
the parent loads an iframe on different domain
the parent polls myframe.contentWindow.location.href (constantly getting Permission denied errors since the frame is on another domain)
iframe processes, then redirects to
http://parentdomain.com/pagethatdoesnotexist?{'result':'ok'}
iframe gets a 404 but now the location is available to the parent
the parent reads the message from the iframe's URL
one possible solution could be to set the name of the iframe with pure js. This name could be read from the wrapping parent page.
Looks to me that your code will request uploadURL twice: first, .submit() do a POST request to upload the file and the result is shown in the iframe as a webpage; second, .getJSON() do a GET request and the result is executed as javascript in <script>. You will realize this if you open up Firebug while testing your app.
Since two of the requests are independent, I have no idea how .getJSON() will give you any information about the file you just uploaded with .submit().
For these kind of cross-domain communication, I would suggest using postMessage; otherwise you will need to change you application workflow to do everything in the iframe after file have uploaded; e.g. do <script>alert('Submission accepted');</script> in the iframe.
What are you trying to do after a user have successfully upload a file?
dont use .html() at all.
I used
jQuery('.someElement')
and it worked for me. you can save the result in a variable and insert it in new element
e.g
var = jQuery('.someElement');
jQuery('.newElement').html(var);

Categories