Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect form field value in Chrome using the back button #11165

Open
mvgn opened this issue Feb 29, 2020 · 15 comments
Open

Incorrect form field value in Chrome using the back button #11165

mvgn opened this issue Feb 29, 2020 · 15 comments

Comments

@mvgn
Copy link

@mvgn mvgn commented Feb 29, 2020

Version

2.6.11

Reproduction link

https://jsfiddle.net/jc26tewa/

Steps to reproduce

  1. Type "Hello" in the message input field.
  2. Click on the link "Another page".
  3. Click on the browser back button.
  4. Click on the "Submit" button.

What is expected?

It is expected that the input field be blank or that Vue recognises its current value and shows "Submitted message: Hello" after clicking on the Submit button.

What is actually happening?

In Chrome, the input field contains the value it had before leaving the page, but Vue thinks the field is empty, so nothing happens when you click on the Submit button. In other browsers, the input field is blank after clicking on the back button.

@posva
Copy link
Member

@posva posva commented Mar 1, 2020

This seems to be a regression on Chromium 79. I filled a bug there: https://bugs.chromium.org/p/chromium/issues/detail?id=1057463#makechanges

@sandipbiswasbehala
Copy link

@sandipbiswasbehala sandipbiswasbehala commented May 14, 2020

is there any solution from vue js end???

@mvgn
Copy link
Author

@mvgn mvgn commented May 31, 2020

I find it strange that this bug has received so little attention as Chrome is the most popular browser and this bug seems to affect every Vuejs form. Even the form on the official Vuejs documentation exhibits the same fault. At https://vuejs.org/v2/guide/forms.html#Text, fill the text box, click a link to another page, and then click the back button. You'll see that the message is blank but the text box is out of sync and contains the previous typed value.

As the Chrome team as marked the related bug as WontFix, it seems it will be up to the Vuejs team to come up with a workaround.

@posva
Copy link
Member

@posva posva commented May 31, 2020

This problem affects every js framework, even raw javascript. As they said, the would look into fixing the regression if enough people at concerned. So please express the need in the reported issue

@sandipbiswasbehala
Copy link

@sandipbiswasbehala sandipbiswasbehala commented Jun 1, 2020

you can do something like this. Resolved my problem as of now. in main js.

window.addEventListener('pageshow', function() {

new Vue({
  render: h => h(App),
}).$mount('#app')

})

@sandipbiswasbehala
Copy link

@sandipbiswasbehala sandipbiswasbehala commented Jun 1, 2020

@mvgn
window.addEventListener('pageshow', function() {

new Vue({
render: h => h(App),
}).$mount('#app')
})

@mvgn
Copy link
Author

@mvgn mvgn commented Jun 2, 2020

@posva, I've commented on the Chrome bug, but I don't know enough to make a technical argument — can only say that other browsers are behaving as expected with Vuejs while Chrome is not.

thanks @sandipbiswasbehala. I'm using Vuejs in a rails app and the default initialisation is with the DOMContentLoaded event, so I'm keeping that for other browsers and changed to the pageshow event just for Chrome.

if (navigator.userAgent.indexOf('Chrome/') > 0) {
  window.addEventListener('pageshow', () => {
    new Vue({
      render: (h) => h(App),
    }).$mount('#app');
  });
} else {
  document.addEventListener('DOMContentLoaded', () => {
    new Vue({
      render: (h) => h(App),
    }).$mount('#app');
  });
}
@Elvaleryn
Copy link

@Elvaleryn Elvaleryn commented Jul 10, 2020

Thanks to @sandipbiswasbehala and @mvgn for the solution, it works perfect on Chrome but unfortunately im having the same issue on Opera. This is quite weird because they are both Chromium based even their dev tools are same. There should be a work around for this, which will solve this problem regardless of which browser.

@Elvaleryn
Copy link

@Elvaleryn Elvaleryn commented Jul 10, 2020

Okay i was digging down because this solution wasn't working for Opera, here is my work around: I found out that when i focus on one of the inputs all the other inputs was becoming empty or default(it is how it should be) So i tried to focus that input as soon as the component is mounted but it did not work. Then i set a time out to focus function then it worked. It seems like for some reason it needs a delay around 300ms to render the state normal. Basically i asynchronously rendered components which has forms now it seems like all of them works flawlessly here is one of them:

const MainComponent = () => ({
	component: import("./Searchbox/MainComponent"),
	delay: 300,
});

Eventhough it works i have no clue why this behaviour exists in Chrome based browsers. Maybe someone else can explain it better.


Here is the related link in vue docs: https://vuejs.org/v2/guide/components-dynamic-async.html
@euoia
Copy link

@euoia euoia commented Jul 12, 2020

On my machine at least, Chrome on OS X is showing the following user agent:

"Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1"

So the looking at user agent for the pageshow workaround doesn't work on Desktop (I haven't tested mobile yet).

I can modify my app.js to wrap my Vue initialisation in the a callback to the pageshow event, which seems to work in Chrome and Safari.

window.addEventListener("pageshow", () => {
  new Vue({
    el: "#app",
  });
});

But I do not know other implications of this, whether it works in all browsers, etc.

I have also noticed that this makes it so the prefilled form fields are reset to the components default values. Ideally Vue would pick up Chrome's prefilled form fields and bind them into its data fields.

I'm also surprised this issue doesn't have more traction.

@aarondfrancis
Copy link

@aarondfrancis aarondfrancis commented Jul 20, 2020

Also running into this.

@andre-brdoch
Copy link

@andre-brdoch andre-brdoch commented Sep 2, 2020

with the autocomplete attribute you can prevent the browser from autofilling your form. However, users will also not receive suggestions anymore.
Here is a dirty hack that prevents it on back-navigation, while still allowing the user to use autocomplete:

<template>
  <form :autocomplete="autocomplete">
    <slot />
  </form>
</template>

<script>
export default {
  data() {
    return {
      // disabled by default, to prevent browsers autofill when navigating backwards after submission
      autocomplete: 'off',
    };
  },

  mounted() {
    // enable after slight delay for the user:
    setTimeout(() => {
      this.autocomplete = 'on';
    }, 200);
  },
};
</script>

@euoia
Copy link

@euoia euoia commented Nov 9, 2020

Just thought I'd add a bit more information on this.

Wrapping new Vue() in the pageshow fixes Chrome but breaks Safari (iOS and desktop). The behaviour you'll see is that the input is empty, but the DOM is still the same as if the input had text.

I haven't found a way to reliably work around this issue in Chrome without breaking Safari. The Vue core contains this code:

export const isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge

https://github.com/vuejs/vue/blob/a9a303009a4267b7f12b956741b4e34dfdc6566f/src/core/util/env.js

Which implies that testing the user agent is reliable. So I wonder whether I was mistaken when I commented previously that the Chrome user agent did not contain the string "chrome". In any case, my version of Chrome now does contain "chrome" so I will go back to inspecting the user agent string.

@raul-technodac
Copy link

@raul-technodac raul-technodac commented Dec 18, 2020

I just used autocomplete="off" on the form inputs and now it shows the default values (or empty value if it's the case), but no more the cached values when hitting the back button.

Hope it helps someone!

@HIMISOCOOL
Copy link

@HIMISOCOOL HIMISOCOOL commented Jan 12, 2021

I have a plain select component in a vue2 sfc and autocomplete="off" doesn't work for me :( will need to look into async component or this pageshow event

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
9 participants