diff --git a/.changeset/tasty-llamas-relate.md b/.changeset/tasty-llamas-relate.md new file mode 100644 index 000000000000..20637dced526 --- /dev/null +++ b/.changeset/tasty-llamas-relate.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +feat: warn users when enhancing forms with files but no `enctype="multipart/form-data"` diff --git a/packages/kit/src/runtime/app/forms.js b/packages/kit/src/runtime/app/forms.js index 4a5a9abfbe0a..30858235032f 100644 --- a/packages/kit/src/runtime/app/forms.js +++ b/packages/kit/src/runtime/app/forms.js @@ -28,13 +28,20 @@ function warn_on_access(old_name, new_name, call_location) { ); } +/** + * Shallow clone an element, so that we can access e.g. `form.action` without worrying + * that someone has added an `` (https://github.com/sveltejs/kit/issues/7593) + * @template {HTMLElement} T + * @param {T} element + * @returns {T} + */ +function clone(element) { + return /** @type {T} */ (HTMLElement.prototype.cloneNode.call(element)); +} + /** @type {import('$app/forms').enhance} */ export function enhance(form_element, submit = () => {}) { - if ( - DEV && - /** @type {HTMLFormElement} */ (HTMLFormElement.prototype.cloneNode.call(form_element)) - .method !== 'post' - ) { + if (DEV && clone(form_element).method !== 'post') { throw new Error('use:enhance can only be used on
diff --git a/packages/kit/test/apps/basics/test/test.js b/packages/kit/test/apps/basics/test/test.js index dfe4c3e11683..740a7c1880c3 100644 --- a/packages/kit/test/apps/basics/test/test.js +++ b/packages/kit/test/apps/basics/test/test.js @@ -828,6 +828,21 @@ test.describe('Matchers', () => { }); test.describe('Actions', () => { + test('Submitting a form with a file input but no enctype="multipart/form-data" logs a warning', async ({ + page, + javaScriptEnabled + }) => { + test.skip(!javaScriptEnabled, 'Skip when JavaScript is disabled'); + test.skip(!process.env.DEV, 'Skip when not in dev mode'); + await page.goto('/actions/file-without-enctype'); + const log_promise = page.waitForEvent('console'); + await page.click('button'); + const log = await log_promise; + expect(log.text()).toBe( + 'Your form contains fields, but is missing the `enctype="multipart/form-data"` attribute. This will lead to inconsistent behavior between enhanced and native forms. For more details, see https://github.com/sveltejs/kit/issues/9819. This will be upgraded to an error in v2.0.' + ); + }); + test(`Accessing v2 deprecated properties results in a warning log`, async ({ page, javaScriptEnabled