I've seen lots of questions about problems with ajax and IE but i haven't found one like this..
The environment is Bootstrap / jQuery / Ajax / parsley / IE-11
I have an ajax script that is working in firefox and chrome. In IE 11, the script will not send... it jumps right to the fail section. It's supposed to pop-up a bootstrap modal with content. The modal pops-up, but it's empty.
the url of the ajax request is the same url as the page it's on...
it's an http request, not an https request.. it's to an internal web server that pings to a 192.168 address.
Ajax requests on an earlier version of this system (between the same url's) that do NOT use bootstrap are working with no problem..
I've turned off all console.log(). didn't help.
I've turn off the server, and it didn't make a difference.. the request isn't getting there...
i've tried lowering all the security settings without going into the custom detail dialog.. no effect..
when i turn back on the console log for fail
i get: Request failed: [object Object] (the object is not clickable)
Something in ie is blocking the request..
<script>
var AjaxSubmit
$("#rbbutton, #ubbutton").click(function() {
AjaxSubmit = $(this).attr("value");
return true;
});
$(function () {
var serverScript = '#serverurl' ; // Server side script we will be calling
$("#rb").submit(function(e) {
var str = $('#rb').serialize();
str = str + '&ajaxfunction=IamBidding' + '&AjaxSubmit='+encodeURIComponent(AjaxSubmit);
if (typeof console == "object") {
}
var request = $.ajax({
type : "POST",
url : serverScript,
data : str,
cache : false,
encode : true
});
request.done(function(data) {
$("#modalbidconfirm").html(data);
$('#bidconfirmmodal').modal('show');
});
request.fail(function( data) {
if (typeof console == "object") {
console.log( "Request failed: " + data );
}
$("#modalbidconfirm").html(data);
$('#bidconfirmmodal').modal('show');
});
e.preventDefault(); // avoid to execute the actual submit of the form.
});
});
</script>
the problem was not in the javascript. the problem was in the html which i did not include in the question.
Firefox and chrome did not have a problem with the serverurl id being defined in a div.
IE would not work unless the serverurl was defined in an input.
<form class="form-inline bidding" ID="rb" name="IamBidding" ACTION="">
i changed this:
<div id="serverurl" value="http://sometingorother.com/?&ajaxfunction=IamBidding"></div>
to this:
<input type="hidden" id="serverurl" value="http://sometingorother.com/?&ajaxfunction=IamBidding" />
and the script works in all 3 browsers.
Related
The server is running CGI, C++ Web API. There is not MVC or PHP involved. The host is using JavaScript, AJAX and some JQuery.
My root question is two fold:
1) How to squirt a raw PDF onto a new window when it returns with that PDF from the POST. Below is an example of a web page that calls a Web API to generate a PDF, which I then do not properly put that PDF into a new web page.
or
2) How to do a POST via an HREF using JavaScript and AJAX.
1 above is preferable. Please reference SQUIRT or HREF in your replies.
If you are an uber Web programmer - search for "Just Not Working" to solve the Squirt issue for me. That will save you a lot of reading.
My code works if the HREF is a GET. The Web API I am calling is returning a PDF. I open a new window and I wrapped the PDF with the proper HTML and all works exactly as I like when I return a static PDF from a GET. But the issue is that I need to push data into the Web API to tell it how to generate the PDF. Since I also want this to atomic, I don't want a post followed by a get. The web api must remove all trace of the data once it returns the PDF. So a single POST would be ideal.
There are other threads on stackoverflow that debate why it is bad to push data in the body of a GET, and since that violates some standards, that is off the table.
Also the data submitted must be secure - submitted via https, so putting it in the URL is no good.
I figured out the dual posting from the form, the same data is submitted to my Web API on a submit - to change the devices settings, and on a button click to generate a PDF.
A stripped down form:
<html>
<head>
<script src="./jquery/jquery-2.1.4.js" type="text/javascript"></script>
<script src="ToolKit.js" type="text/javascript"></script>
<script src="setupFunctions.js" ></script>
<link rel="stylesheet" type="text/css" href="yadayada.css" />
<title>My Linux Device with CGI scripts</title>
</head>
<div class="body">
<form name="MyForm" id="MyForm" hidden action="/api/config/form" method="POST">
<div class="variables">
<input type="hidden" id="ETH0_IP_MODE" name="ETH0_IP_MODE" value="DHCP">
<input type="hidden" id="WIFI_AP_BROADCAST" name="WIFI_AP_BROADCAST" value="ON">
</div>
<!-- HTML That does amazing and spectacular stuff, and sets name/value items to post. -->
<div id="bottomButtons">
<input type="submit" name="update" value="Apply settings" />
<input type="button" value="Cancel" onclick="location.reload(true);" />
<input type="button" id="GeneratePDF" value="Create PDF" onclick="GeneratePDF()" style="float:right;" />
</div>
</form>
</div> <!-- body -->
</html>
Above is a stripped down form with two buttons. Submit does a post but I overload the post to change the error/success.
<!-- now some Javascript -->
<script type="text/javascript">
function UpdateStatus(st, color) { <!-- here for completeness... --> }
$('form[name=MyForm]').submit(function (e) {
e.preventDefault(); // Keep the form from submitting
var form = $(this);
$.ajax({
url: form.attr('action'), // '/api/config/form',
type: form.attr('method'), // 'POST',
data: form.serialize(),
cache: false,
async: false,
dataType: 'html',
error: function (jqXHR, textStatus, errorThrown) {
UpdateStatus('Status: Error setting the network configuration! ' + textStatus + ': ' + errorThrown, "Crimson");
},
success: function (data) {
UpdateStatus('Status: Success set the network configuration!', "Chartreuse");
my_window = window.open("", "Update Network Configuration Results", "location=1,status=1,scrollbars=1,width=800,height=640");
my_window.document.write(data);
}
});
return false;
});
</script>
So far this is just a normal form that calls a Web API. Nothing special. After submit/update button is pressed, status is updated and on success a window is opened. That window receives a block a text that is returned from the Web API that is there for debugging. It reports back everything that has changed.
The main issue is the second button - the GeneratePDF. I do call a POST (see below), but my primary issue is how to squirt the PDF into the HTML on successful return from the post.
More JavaScript - linked to that second button:
function GetPDF() {
try {
var elem = document.getElementById('MyForm');
WebToolkit.readPDF(GeneratePDF_callback, elem); // POST
} catch (e) {
debugger;
throw e;
}
}
Now some AJAX:
var WebToolkit = {
host: document.location.host, // Javascript Get Website URL
servicePath: "/api/config/",
getValueMethod: "value?",
getPDFMethod: "GeneratePDF?",
httpsPortNumbers: [443],
_networkErrorCallback: null,
_serviceURL: null,
readPDF: function (callback, form) {
var url = this._serviceURL + this.getPDFMethod;
$.ajax({
type: "POST",
contentType: "application/pdf",
dataType: "text",
data: $("form").serialize(),
url: url,
timeout: 5000,
success: callback,
cache: false,
async: false
});
}
}
Obviously -serviceURL is setup in a setup function which I did not show. But you get the idea. All of this works. When I press the GeneratePDF button - it posts the data and the Web API (not shown) returns a raw PDF file. My callback is :
GeneratePDF_callback. And THIS is the problem code that I need help with. I am leaving in commented out attempts to wrap the PDF - which do not work.
function GeneratePDF_callback(data)
{
try {
my_window = window.open("", "GeneratePDF Results", "location=1,status=1,scrollbars=1,width=1024,height=800");
// Next two lines are just not working !!!
var PDFData = encodeURI(data);
my_window.document.body.innerHTML = "<head><Title>Generate PDF</Title><style></style></head><body><object data=:application/pdf;base64,\"" + PDFData + "\" type=\"application/pdf\" width=\"100%\" height=\"100%\"><p>It appears you don't have a PDF plugin for this browser. Not a problem... you can click here to download the PDF file.</p></object></body></html>";
UpdateStatus('Status: Success reading PDF from device!', "Chartreuse");
} catch (e) {
debugger;
UpdateStatus('Error reading PDF: ' + e.message, "Crimson");
throw e;
}
}
FRIGGIN HELP ! This is driving me batty. Once this works - as you can see I have an href after the "Not a problem". This is why I think getting an HREF to work is preferable. Clicking that link will resubmit the data and request a new PDF document. And this in itself may be a major design flaw, since I haven't quite tackled how I'd resubmit the data from the new window.
Alternately clicking the button could do a POST of the data, and a GET of the results. The POST would return an ID, the GET would obtain the ID, and only allow ONE get of that ID. There is no refresh on the GET since it simply displays or stores the PDF. A refresh on the Window showing the PDF would not need to resubmit the query. This must be SECURE - HTTPS with none of the data visibly insecure from a sniffer.
If you're still with me - THANK YOU just for reading.
SOLUTION:
I got this working, and am a bit overdue getting back to update this post:
I use GET and pass in the parameters to tell the server how to build the PDF.
I get back the html with an embedded object, which represents the PDF stream.
HTTP/1.1 200 OK
X-Frame-Options: DENY
Content-Length: 265129
Content-Type: application/pdf
Date: Wed, 17 Feb 2016 07:19:29 GMT
Server: lighttpd/1.4.35
%PDF-1.3
... all the PDF binary data...
This is done in JavaScript via:
form = $('form[name=myForm]');
PDF_window = window.open("", "PDF Results", "location=1,status=1,width=700,height=800");
if PDF_window == undefined) {
UpdateStatus("Status: Error opening window to display the PDF! Turn on POP UPS.", "Chartreuse");
}
else {
Data = WebToolkit._serviceURL+"PDF?" + form.serializeAndEncode();
}
WebPage = "<html><Title>PDF Page</Title><body><p>click here to download the PDF file for saving.</p><object data=\"" + Data + "\"type=\"application/pdf\" width=\"100%\" height=\"100%\"></object></body></html>";
PDF_window.document.clear();
PDF_window.document.write(WebPage);
The only issue I have run into is that embedded PDF will not allow me to press the SAVE icon. It works for PRINT, this is why I put the URL to redraw the page and that redraws the page exactly as it had previously - but not inside the 'object data'. Then it allows SAVE and PRINT. Weird, I see lots of people asking how to draw a PDF and disallow SAVE. Well I want the opposite, my solution is OK, for now.
Update - Solution, which is pretty simple after much experimentation:
function DisplayPDFResult() {
var form;
form = $('form[name=MyForm]');
PDFWindow = window.open("", "Yada Header", "location=0,status=1,width=700,height=800,", false);
if (PDFWindow == undefined) {
UpdateStatusPop("Status: Error opening window to display the EasySetup PDF! Turn on POP UPS.", "ForestGreen");
return;
}
else {
// This url will cause the web api to generate a raw pdf, and squirt into the window
PDFWindow.location.href = WebToolkit._serviceURL+"ShowPDF?" + form.serializeAndEncode();
}
}
Vinnie
I have the following code that runs when the process_2banner button is clicked on a html page. This code does what is supposed to do when using Firefox. When using Chrome and Internet Explorer the ajax code is called but the div spinner_block does not show/hide as the code intends to.
Strangely enough it works if I open firebug in Chrome and place a breakpoint right before the ajax call (after the .css("display","block") statement. The spinner_box <div> shows, and then after the ajax call returns, it hides.
Can you see what is wrong here?
Thank you very much!
Andres
$('#process_2banner').on("click",function() {
var postdata = "lead_id="+rowId; //needs to include the pidm of the user clicking the button
$('#spinner_box').css("display","block");
$('#spinner_box').html('Wait, we are processing the record..');
$('#spinner_box').css("display","block");
$.ajax({type: "POST",
url: "insert_srwordpress.php",
data:postdata,
success:function(result) {
if (result.isOk == false) {
alert('Some error occurred while writing Banner') }
else {
$('#spinner_box').hide();
}
},
async: false});
});
The response result is an string in format JSON?
May you need parse the JSON before use it?
Example:
var jData = $.parseJSON(result);
if (jData.isOk === false) {
}
I am having a strange issue with an AJAX call where it is working in Firefox, but not in IE. When I add an IE alert(), I see the returned content, but it does not want ot insert with the jQuery .html() command. Here is my sample code:
$(document).on('click','.OpenForm',function(e) {
e.preventDefault();
var FormControl = $(this).attr('id'); //ex: id=FormView_12 or FormEdit_12
FormControl = FormControl.split('_');
var FormControlType = FormControl[0];
var FormID = FormControl[1];
$.post("./includes/Getform.php", { "t" : "view" , FormID : FormID })
.done(function(data) {
if (data.length>0){
data = data.replace(/(\r\n|\n|\r)/gm,"");
//alert(data); ---THIS ALERTS THE RESPONSE IN IE8
//console.log(data); --- THIS SHOWS RESPONSE IN FF
$('.ProjectContentLoad').html(data).show();
}
})
.fail( function(xhr, textStatus, errorThrown) {
error_handling(xhr.responseText);
});
});
Perhaps your returned HTML is invalid. FF doesn't have problems with that, but IE8 sure does ;) Maybe you forget to close a div?
The following post shows some guys having the exact same problem: jQuery AJAX GET html data IE8 not working
Just a shot in the dark, but IE isn't getting confused by the JS object you're sending is it?
{ "t" : "view" , FormID : FormID }
Is there any reason you're using a string as a key for "t"?
Do you have any error message on your JS console ? Can you show what data content is ?
I'm thinking about 2 things:
1) If you don't run development tools in IE8, console.log() is undefined. To solve it, put this code at the top of your page :
<script type="text/javascript"> if (!window.console) console = {log: function() {}}; </script>
source : 'console' is undefined error for Internet Explorer
2) Maybe an AJAX cache issue with IE (I don't think because you are using post() ), try to put this code at the top of your page :
$.ajaxSetup({ cache: false });
source: How to prevent a jQuery Ajax request from caching in Internet Explorer?
I'm using ajax to get some data then based on the data use html() to put it on the page.
In IE, the data returned is empty (it's html). It still triggers the success function, but the html is not there. I've set the dataType: "text" but still doesn't work.
Any ideas?
Thanks!
EDIT:
Here's the exact code:
$('#frm').submit(function(event){
event.preventDefault();
var self = this;
z = $('#zipcode');
if(z.val() != '' && z.val().length == 5) {
var value = z.val().replace(/^\s\s*/, '').replace(/\s\s*$/, '');
var intRegex = /^\d+$/;
if(!intRegex.test(value)) {
return false;
}
} else {
return false;
}
$.ajax({
url: "/ajax/zip",
type: 'GET',
async: false,
dataType: 'html',
data: {zipcode: $('.zip_field').val()},
success: function(data) {
if(data == 'false'){
error($(".zip_field"));
return false;
}else{
self.submit();
$('.container').empty().append(data);
}
}
});
})
It's submitting a zip code. On submit, it checks to make sure it's a number and 5 digits in length. If that passes, it goes to the ajax and checks to make sure it's a valid zip code (database check), if that fails it returns 'false' as text, if it's good then it returns some html.
It works in Firefox and Chrome, but not in IE. When it's good, it submits the form but the data returned alerts empty and is appended as empty space.
demo: https://so.lucafilosofi.com/jquery-ajax-return-data-empty-in-ie/
your code don't work simply because it is buggy, it have nothing to do with IE.
it should be something like below.
$('#frm').submit(function (e) {
e.preventDefault(); // this one already act as return false...
var form = $(this);
// why you have .zip_field & #zip_code ?
var zip_code = $.trim($('#zip_code').val());
var valid = (zip_code.length === 5 && !isNaN(zip_code)) ? true : false;
if (valid) {
$.get('/ajax/zip', {
zipcode: zip_code
}, function (data) {
if (data == 'false') {
alert('error!');
} else {
//if you submit the form here
//form.submit(); then the line below
//is totally useless
$('.container').html(data);
//.empty().append() is = .html()
}
});
}
});
NOTE: the fact that chrome and firefox don't display errors dosn't mean that errors are not there; internet-explorer simply tend to display errors everytime it run through malformed code etc. Also i strongly doubt that your code work really as expected since it is not so good as you may think. I guess the problem is in your code and have nothing to do with jQuery itself or it's ajax function or dataType.
One thing could be that this URL is cached by the browser. If you obtain a 304 status your response's text it will be empty. Check your HTTP cache headers, and adjust them properly. You could also trying to use POST (only GET are cached).
Also, have a look to Content-Length if is properly set.
If nothing of above works, inspect the network's call will give to you (and us) some additional details, try the IE's dev tools.
You could also try to have the same request using XMLHttpRequest's object directly (assuming you're using IE>6).
I have same problem in IE and Google Chrome
$.ajax is not working in this browser because of security reason.
so if you want to run explicitely
for chrome run chrome with
chrome.exe --disable-web-security
and in IE you need to change setting from Menu>Tools>internet Options
Some versions of IE will not ~repair~ invalid HTML in XHR requests and simply discard it; I've been bitten by this before.
Make sure the HTML returned is valid for the doctype IE thinks you're using (use the developer tools in IE to see), and check your HTML with a validator tool. Obviously, it will complain about missing <html>, <head>, etc, but ignores those and focus on the other errors. once you've fixed those, it should start working.
Also, aSeptik's answer is full of good tips to improve your code.
Hit an interesting problem today when trying to upload an image file < 2MB using dojo.io.iframe.
My function to process the form is called, but before the form is posted to the server I am getting the following error:
TypeError: ifd.getElementsByTagName("textarea")[0] is undefined
My function that is used to action the post of the form is :
function uploadnewlogo(){
var logoDiv = dojo.byId('userlogo');
var logoMsg = dojo.byId('uploadmesg');
//prep the io frame to send logo data.
dojo.io.iframe.send({
url: "/users/profile/changelogo/",
method: "post",
handleAs: "text",
form: dojo.byId('logoUploadFrm'),
handle: function(data,ioArgs){
var response = dojo.fromJson(data);
if(response.status == 'success'){
//first clear the image
//dojo.style(logoDiv, "display", "none");
logoDiv.innerHTML = "";
//then we update the image
logoDiv.innerHTML = response.image;
}else if(response.status == 'error'){
logoMsg.innerHTML = data.mesg;
}else{
logoMsg.innerHTML = '<div class="error">Whoops! We can not process your image.</div>';
}
},
error: function(data, ioArgs){
logoMsg.innerHTML = '<div class="error">' + data + '</div>';
}
});
}
The form is very basic with just a File input component and a simple button that calls this bit of javascript and dojo.
I've got very similar code in my application that uploads word/pdf documents and that doesn't error, but for some reason this does.
Any ideas or pointers on what I should try to get this to work without errors?
Oh I'm using php and Zend framework for the backend if that has anything to do with it, but I doubt it as it's not even hitting the server before it fails.
Many thanks,
Grant
Another common reason for this error is the server isn't packaging the data correctly. This means even if you have set "handleAs: json" you have to send that json wrapped in some html. This is what it should look like:
<html>
<body>
<textarea>
{ payload: "my json payload here" }
</textarea>
</body>
</html>
Your error was saying it couldn't find the textarea in your return from the server. For more look at http://docs.dojocampus.org/dojo/io/iframe
Since the load handler of dojo.io.iframe.send() has been triggered, the request should have been sent to the server and response is back. I think the response from server is not correct. Maybe the server returns an error page.
Use Firebug to inspect current page's DOM and find the transporting iframe created by Dojo and check its content. Firebug can capture iframe I/O too, check its Net tab. You may find the root cause of this issue.
Did you respect the constraint written in the doc ?
IMPORTANT: For all values EXCEPT html and xml, The server response should be an HTML file with a textarea element. The response data should be inside the textarea element. Using an HTML document is the only reliable, cross-browser way this transport can know when the response has loaded. For the text/html (Or XML) mimetype, just return a normal HTML/XML document. In other words, your services for JSON and Text formats should return the data wrapped as the following: