[Does NOT work in Firefox] 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 formDataFilter = function(formData) {
if (!(window.FormData && formData instanceof window.FormData)) return formData
if (!formData.keys) return formData // unsupported browser
var newFormData = new window.FormData()
Array.from(formData.entries()).forEach(function(entry) {
var value = entry[1]
if (value instanceof window.File && value.name === '' && value.size === 0) {
newFormData.append(entry[0], new window.Blob([]), '')
} else {
newFormData.append(entry[0], value)
}
})
return newFormData
}
var submit = function(filter) {
var $result = $('#result')
var $echo = $('#echo')
var formData = new FormData($('form')[0])
if (filter) {
formData = formDataFilter(formData)
}
$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) })