Skip to content

Instantly share code, notes, and snippets.

@ypresto
Last active May 11, 2018 09:21
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ypresto/b4715b06230d4014a90eaacc3445158f to your computer and use it in GitHub Desktop.
Save ypresto/b4715b06230d4014a90eaacc3445158f to your computer and use it in GitHub Desktop.
[Does NOT work in Firefox] iOS 11.3 Safari / macOS Safari 11.1 empty <input type="file"> XHR bug workaround for rails-ujs / jquery_ujs
// iOS 11.3 Safari / macOS Safari 11.1 empty <input type="file"> XHR bug workaround.
// Replace empty File object with equivalent Blob in FormData, keeping its order, before sending it to server.
// Should work with IE10 and all other modern browsers.
// Because useragent value can be customized by WebView or etc., applying workaround code for all browsers.
// https://stackoverflow.com/questions/49614091/safari-11-1-ajax-xhr-form-submission-fails-when-inputtype-file-is-empty
// https://github.com/rails/rails/issues/32440
document.addEventListener('ajax:beforeSend', function(e) {
var formData = e.detail[1].data
if (!(formData instanceof window.FormData)) return
if (!formData.keys) return // 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)
}
})
e.detail[1].data = newFormData
})
@ypresto
Copy link
Author

ypresto commented Apr 14, 2018

This keeps the order parts in FormData, compliant with <form> specification.

Detail: https://stackoverflow.com/a/49827426/1474113

For jQuery $.ajax(), see here: https://jsfiddle.net/ypresto/y6v333bq/

@ypresto
Copy link
Author

ypresto commented Apr 14, 2018

UPDATE: This does not work in Firefox.

Firefox returns just empty string for FormData.get() on empty file field (instead of File object in other browsers). So when using this old workaround, empty <input type="file"> will be sent like as empty <input type="text">. Unfortunately, there is no way to distinguish an empty file from an empty text after creating FormData object.

Use this solution instead: https://gist.github.com/ypresto/cabce63b1f4ab57247e1f836668a00a5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment