Vue-router: replaceState Error when path starts with // and scrollBehavior is set

Created on 22 Jan 2019  ·  8Comments  ·  Source: vuejs/vue-router

Version

3.0.2

Reproduction link

https://github.com/yegorLitvinov/vue-router-bug

Steps to reproduce

Set scrollBehavior property in router config. Put two forward slashes into beginning of the url (e.g. http://localhost:8081//about)

What is expected?

No errors in console

What is actually happening?

In firefox: SecurityError: The operation is insecure.
In Chrome: Uncaught DOMException: Failed to execute 'replaceState' on 'History': A history state object with URL 'http://about/' cannot be created in a document with origin 'http://localhost:8081' and URL 'http://localhost:8081//about'

fixed on 4.x

Most helpful comment

I faced this issue too.

Steps to reproduce:

  1. Build
  2. deploy to primary.domain.com
  3. deploy to secondary.domain.com
  4. Add <base href="https://primary.domain.com" target="_blank"> into secondary.domain.com
  5. Access url secondary.domain.com then saw this issue

Debug info

vue: 2.5.17
vue-router: 3.0.6,

vue-router/dist/vue-router.js:1550

function setupScroll () {
  // Fix for #1585 for Firefox
  // Fix for #2195 Add optional third attribute to workaround a bug in safari https://bugs.webkit.org/show_bug.cgi?id=182678
  window.history.replaceState({ key: getStateKey() }, '', window.location.href.replace(window.location.origin, '')); // ======> This line cause the issue
  window.addEventListener('popstate', function (e) {
    saveScrollPosition();
    if (e.state && e.state.key) {
      setStateKey(e.state.key);
    }
  });
}

The temporary solution:
Comment the bellow line to avoid setupScroll => Then implement scrollBehavior by your self on route changed:

const Router = new VueRouter({
    scrollBehavior: () => ({ y: 0 }), // ===> Comment this line to avoid setupScroll => Then implement scrollbehavior by your self on route change.
    routes: ...,
  })

If you ignore scrollBehavior key, setupScroll() will not be executed.

Hope this help!

All 8 comments

It looks like we should sanitize the beginning of the URL so it doesn't contain trailing slashes but I'm still unsure about it. I will have to search a bit more

I faced this issue too.

Steps to reproduce:

  1. Build
  2. deploy to primary.domain.com
  3. deploy to secondary.domain.com
  4. Add <base href="https://primary.domain.com" target="_blank"> into secondary.domain.com
  5. Access url secondary.domain.com then saw this issue

Debug info

vue: 2.5.17
vue-router: 3.0.6,

vue-router/dist/vue-router.js:1550

function setupScroll () {
  // Fix for #1585 for Firefox
  // Fix for #2195 Add optional third attribute to workaround a bug in safari https://bugs.webkit.org/show_bug.cgi?id=182678
  window.history.replaceState({ key: getStateKey() }, '', window.location.href.replace(window.location.origin, '')); // ======> This line cause the issue
  window.addEventListener('popstate', function (e) {
    saveScrollPosition();
    if (e.state && e.state.key) {
      setStateKey(e.state.key);
    }
  });
}

The temporary solution:
Comment the bellow line to avoid setupScroll => Then implement scrollBehavior by your self on route changed:

const Router = new VueRouter({
    scrollBehavior: () => ({ y: 0 }), // ===> Comment this line to avoid setupScroll => Then implement scrollbehavior by your self on route change.
    routes: ...,
  })

If you ignore scrollBehavior key, setupScroll() will not be executed.

Hope this help!

wow, thanks for this issue. Just faced this as well, exact same scenario as @luatnd desribed.

@posva any news about this?

Hi,
The temporary solution from @luatnd doesn't always work.
Any progress on this bug ?

I'm also seeing this problem, but with $ sign in the querystring.

I'm experiencing this problem as well.

In my case the original URL looks like https://site.com//?x=y, which results in calling replaceState with //?x=y as the URL. I put in a place a workaround to detect the situation and trim the duplicate / before initializing the router.

This comment has some useful info: https://github.com/ReactTraining/react-router/issues/3184#issuecomment-293370088
Note that although I'm linking to an issue in a react package, I am actually experiencing this issue in vue router. 😛 It seems this same issue is referenced in lots of different contexts, so it must be a common / easy problem to run into. Either that or different libs have based their browser history code on the same original source.

I was having this issue as well. The only thing I was using scrollBehavior for was to scroll the user to the top of the page.

Before:

const router = new VueRouter({
  base: process.env.BASE_URL,
  routes,
  scrollBehavior() {
    return { x: 0, y: 0 };
  },
});

After:

const router = new VueRouter({
  base: process.env.BASE_URL,
  routes,
});

router.afterEach(() => {
  window.scrollTo(0, 0);
});
Was this page helpful?
0 / 5 - 0 ratings