admin管理员组文章数量:1353311
I'm trying to submit a form via Ajax with JavaScript. It works on IE, Firefox, Chrome and iOS in Browserstack, but it doesn't work in iOS Simulator or a real iOS device or desktop Safari.
I've tried XMLHttpRequest onload
and XMLHttpRequest onreadystatechange
, neither gets triggered. As far as I can tell request.open('POST', url, true);
isn't working. console.log('2');
never gets triggered either.
I added this for debugging:
request.send(data);
console.log(request);
setTimeout(function(){ console.log(request); }, 3000);
They both return readyState: 1 in Safari, in other browsers the first one returns readyState: 1 and the second one returns readyState: 4 as expected.
Here's my code pared down to the essentials:
$('.ajax-form').submit(function(event) {
var form = event.target;
var data = new FormData(form);
var request = new XMLHttpRequest();
var method = form.getAttribute("method");
var action = form.getAttribute("action");
var url = window.location.href
request.open('POST', url, true);
request.setRequestHeader("X-Requested-With", "XMLHttpRequest");
request.setRequestHeader("HTTP_X_REQUESTED_WITH", "XMLHttpRequest");
request.setRequestHeader("pragma", "no-cache");
console.log('1');
request.onreadystatechange = function() {
console.log('2');
if (request.readyState === 4 && request.status === 200) {
var response = JSON.parse(request.response);
if (response.success && response.finished) {
// Go to selected success page
window.location.href = $(form).find('[name="formReturnUrl"]').attr('value');
} else if (response.errors || response.formErrors) {
// Deal with errors
}
}
};
request.send(data);
console.log(request);
setTimeout(function() {
console.log(request);
}, 3000);
event.preventDefault();
});
All my iOS testing is on iOS 11 in Safari. I've read a few things about iOS being weird, but I haven't found a solution that works for me. What am I doing wrong?
I'm trying to submit a form via Ajax with JavaScript. It works on IE, Firefox, Chrome and iOS in Browserstack, but it doesn't work in iOS Simulator or a real iOS device or desktop Safari.
I've tried XMLHttpRequest onload
and XMLHttpRequest onreadystatechange
, neither gets triggered. As far as I can tell request.open('POST', url, true);
isn't working. console.log('2');
never gets triggered either.
I added this for debugging:
request.send(data);
console.log(request);
setTimeout(function(){ console.log(request); }, 3000);
They both return readyState: 1 in Safari, in other browsers the first one returns readyState: 1 and the second one returns readyState: 4 as expected.
Here's my code pared down to the essentials:
$('.ajax-form').submit(function(event) {
var form = event.target;
var data = new FormData(form);
var request = new XMLHttpRequest();
var method = form.getAttribute("method");
var action = form.getAttribute("action");
var url = window.location.href
request.open('POST', url, true);
request.setRequestHeader("X-Requested-With", "XMLHttpRequest");
request.setRequestHeader("HTTP_X_REQUESTED_WITH", "XMLHttpRequest");
request.setRequestHeader("pragma", "no-cache");
console.log('1');
request.onreadystatechange = function() {
console.log('2');
if (request.readyState === 4 && request.status === 200) {
var response = JSON.parse(request.response);
if (response.success && response.finished) {
// Go to selected success page
window.location.href = $(form).find('[name="formReturnUrl"]').attr('value');
} else if (response.errors || response.formErrors) {
// Deal with errors
}
}
};
request.send(data);
console.log(request);
setTimeout(function() {
console.log(request);
}, 3000);
event.preventDefault();
});
All my iOS testing is on iOS 11 in Safari. I've read a few things about iOS being weird, but I haven't found a solution that works for me. What am I doing wrong?
Share Improve this question edited Jul 6, 2018 at 6:24 user7637745 9852 gold badges14 silver badges27 bronze badges asked Jul 5, 2018 at 23:10 Simon KuranSimon Kuran 2552 silver badges11 bronze badges 2-
I don't know why this is happening but I remend trying
$.post()
, since you're already using jQuery. – user5734311 Commented Jul 5, 2018 at 23:27 - Thanks for the idea, but jQuery Ajax isn't correctly returning form error data from my CMS (Craft running Freeform). I'm trying to use pure JavaScript for the Ajax since that works perfectly in my environment, except in iOS Safari... Any other ideas? – Simon Kuran Commented Jul 5, 2018 at 23:59
2 Answers
Reset to default 8Solved. Thanks to @mxcoder for pointing me in the right direction.
Safari (desktop and iOS) have a bug when creating FormData with empty file fields. I solved this by disabling empty file fields right before creating FormData and then re-enabling them right after so the form can be reused after the Ajax is submitted.
I changed var data = new FormData(form);
to this:
// Disable empty file fields before submitting.
if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1) {
var $inputs = $('input[type="file"]:not([disabled])', form);
$inputs.each(function(_, input) {
if (input.files.length > 0) return
$(input).prop('disabled', true);
});
}
var data = new FormData(form);
// Re-enable empty file fields after creating FormData.
if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1) {
$inputs.prop('disabled', false);
}
- If the browser is Safari, disable empty
<input type="file">
elements - Create FormData
- If the browser is Safari, re-enable empty
<input type="file">
elements. This allows the form to be reused after successful submission or after correcting errors.
Interesting problem, Safari is indeed tricky sometimes.
I don't have a solution yet for you but can you try the following:
- Try not using FormData, maybe iOS doesn't play nicely with XHR + FormData yet, it could be a bug worthy to report!
- Can you share the request and response body and headers? Maybe there's something in the server side failing for the iOS request, again, maybe some misplaced header.
本文标签: javascriptiOS Safari fails to send form data via AJAXStack Overflow
版权声明:本文标题:javascript - iOS Safari fails to send form data via AJAX - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1743921918a2562249.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论