Safari 11 XHR bug workaround
iOS 11.3 Safari / macOS Safari 11.1 empty <input type="file"> XHR bug workaround
by ypresto
HTML
<div id="main">
<form>
<div>
Select File (leave this empty) <input type="file" name="file">
</div>
<div>
Text <input type="text" name="html" value="foobar">
</div>
<button id="submit-as-is-button" type="button">Submit as-is</button>
<button id="submit-filtered-button" type="button">Submit w/ input filtered</button>
</form>
<div id="result">The result will be shown here.</div>
<div id="echo">Request body will be shown here.</div>
</div>
CSS
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#main {
background: #fff;
border-radius: 4px;
padding: 20px;
text-align: center;
transition: all 0.2s;
margin: 0 auto;
width: 400px;
}
#main div {
margin: 4px;
padding: 4px;
border: 1px solid #ccc;
}
#main #result {
margin-top: 24px;
}
button {
background: #0084ff;
border: none;
border-radius: 5px;
padding: 8px 14px;
font-size: 15px;
color: #fff;
}
JavaScript
// iOS 11.3 Safari / macOS Safari 11.1 empty <input type="file"> XHR bug workaround.
var getFormData = function(form) {
var $inputs = $('input[type="file"]:not([disabled])', form)
$inputs.each(function(_, input) {
if (input.files.length > 0) return
$(input).prop('disabled', true)
})
var formData = new FormData(form)
$inputs.prop('disabled', false)
return formData
}
var submit = function(filter) {
var $result = $('#result')
var $echo = $('#echo')
var formData = filter ? getFormData($('form')[0]) : new FormData($('form')[0])
$result.text('In Progress')
$.ajax({
type: 'POST',
enctype: 'multipart/form-data',
url: '/echo/html/',
data: formData,
contentType: false,
processData: false,
cache: false,
complete: function(xhr) {
$result.text(xhr.status + ' ' + xhr.statusText)
$echo.text("" + xhr.responseText)
}
})
}
$("#submit-as-is-button").on("click", function() { submit() })
$("#submit-filtered-button").on("click", function() { submit(true) })