当重新访问URL时,Vue路由器返回404

时间:2016-04-04 09:47:57

标签: vue.js vue-router

我只启用了Vue路由器历史记录模式。当我通过v-href或href访问vue路由时,它工作正常。但是,当我尝试刷新该页面或直接从浏览器地址栏运行时,它只返回404.是否有任何选项可以接受刷新/重新访问该URL?

以下是我的Vue路由器配置

'meta_key' = '_tax_class'

14 个答案:

答案 0 :(得分:18)

通过刷新页面,您使用当前URL向服务器发出请求,服务器返回404.您必须在Web框架或Web服务器级别处理此问题。

https://router.vuejs.org/en/essentials/history-mode.html

答案 1 :(得分:10)

我认为你错过了SPA不是服务器端渲染。至少对大多数人而言。因此,当您访问/任何您的Web服务器不会将其重定向到index.html时。但是,如果你点击任何vuejs路由器链接,它将起作用,因为javascript开始行动,而不是服务器端。

要解决此问题,请使用.htaccess并将所有请求重定向到index.html,如此

<ifModule mod_rewrite.c>
    RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</ifModule>

希望它有所帮助!

答案 2 :(得分:2)

如果有人在.NET Core中将此问题作为应用程序的后端处理,那么一个很好的方法是在.NET Core应用程序的Startup.cs中使用简单的回退处理程序:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
        ....Your configuration
      app.UseMvc(routes =>
      {
        routes.MapRoute(
                  name: "default",
                  template: "{controller=Home}/{action=Index}/{id?}");
      });
      //handle client side routes
      app.Run(async (context) =>
      {
        context.Response.ContentType = "text/html";
        await context.Response.SendFileAsync(Path.Combine(env.WebRootPath, "index.html"));
      });
    }
 }

有关详情:http://blog.manuelmejiajr.com/2017/10/letting-net-core-handle-client-routes.html

答案 3 :(得分:2)

(在Ubuntu上)具有root用户访问权限的更好的方法是修改/etc/apache2/apache2.conf,因为在这种情况下,即使Apache本身discourage也会使用.htaccess

请注意,首先,您必须要做

sudo a2enmod rewrite

然后,将以下块添加到/etc/apache2/apache2.conf

<Directory /var/www/html/>
        RewriteEngine On
        RewriteBase /
        RewriteRule ^index\.html$ - [L]
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule . /index.html [L]
</Directory>

之后,做

sudo systemctl restart apache2

对我来说,这是完美无缺的,因为它不仅将Vue创建的路由重定向回/,而且实际上将网站刷新到相同的路由,因此刷新后您仍处于相同的视图。 / p>

答案 4 :(得分:1)

即使在尝试上述解决方案后,任何人仍面临问题,请找到以下方法。 如果您有vue.config.js,其中有

module.exports = {
  publicPath: process.env.PUBLIC_URL || "", // <-- this is wrong
  ...
};

要么删除vue.config.js,要么尝试从导出对象中删除publicPath。

如果您不想删除publicPath,也可以尝试以下方法

module.exports = {
  publicPath: process.env.PUBLIC_URL || "/", default)
  transpileDependencies: ["vuetify"],
};

答案 5 :(得分:0)

对于使用Express后端看到此消息的人,中间件connect-history-api-fallback的实现方式

const express = require('express');
const history = require('connect-history-api-fallback');

const app = express(); 
app.use(history({
  index: '/' //whatever your home/index path is default is /index.html
}));

或通过本机节点

const http = require('http')
const fs = require('fs')
const httpPort = 80

http.createServer((req, res) => {
  fs.readFile('index.htm', 'utf-8', (err, content) => {
    if (err) {
      console.log('We cannot open "index.htm" file.')
    }

    res.writeHead(200, {
      'Content-Type': 'text/html; charset=utf-8'
    })

    res.end(content)
  })
}).listen(httpPort, () => {
  console.log('Server listening on: http://localhost:%s', httpPort)
})

两者都是documentation中的建议。

答案 6 :(得分:0)

还有其他人遇到同样的问题,我才意识到

"book/:bookId/read"  // this will not work after page reload

这是不同的

"/book/:bookId/read" // this is what works even after page reload

这当然是在遵循其他家伙提出的建议之后,更重要的是在您的应用服务器端捕获所有路由。 我实际上不知道为什么这样做,但是任何有任何想法的人都可以告诉我们。

答案 7 :(得分:0)

如果您不太在乎网址中的哈希,则可以将模式设置为在路由器配置文件中进行哈希:mode: 'hash' 无需设置服务器端即可正常工作。

答案 8 :(得分:0)

我正在将Razor Pages与.net core 2.2一起使用,并且可以正常工作:

app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller}/{action=Index}/{id?}");

            routes.MapRoute(
                name: "spa-fallback",
                template: "{*url:regex(^((?!.css|.map|.js|sockjs).)*$)}",
                defaults: new { controller = "Index", action = "Index" });

        });

答案 9 :(得分:0)

对于Netlify,请将以下内容添加到public/_redirects文件中...

/*    /index.html   200

请参见https://www.netlify.com/docs/redirects/#history-pushstate-and-single-page-apps

答案 10 :(得分:0)

来晚了,但是.....

如果有人对此感兴趣,请执行以下操作:

  1. 将对已知客户端URL的请求重定向到索引(但只有已知的客户端URL,这样,您可以保留404用于未找到的页面实际URL)。您如何执行此操作取决于您的服务器。当时我使用的是烧瓶,只是增加了更多路线。

  2. 向根vue元素添加属性

    <div id="content" redirect_to="{{redirect_to}}"></div>

在我的视图函数将参数替换为URL请求的实际路由的地方

  1. 在根vue组件中,检查该属性并检索其值,如下所示:

if(this。$ el.attributes ['redirect_to']。value!==“”)path = this。$ el.attributes ['redirect_to']。value

  1. 使用属性值调用$ router.push

this。$ router.push(path).catch(err => {})

(需要捕获,否则路由器将引发NavigationDuplicated错误。)

之所以这样做,是因为SPA中的URL的全部要点是因为它们指向特定的资源,所以我希望我的用户能够使用这些URL来返回这些相同的资源。

希望这可以帮助某人或为他们指明正确的方向,使其适合他们的特定需求。

答案 11 :(得分:0)

就我而言,这是在以天蓝色CDN下的静态网站托管在天蓝色blob存储中的SPA中发生的。 以下问题的解决方案为我解决了该问题(在CDN端点中应用了修复程序):Hosting SPA with Static Website option on Azure Blob Storage (clean URLs and Deep links)

答案 12 :(得分:0)

那太简单了,您只需要在服务器上添加此配置:

Apache

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</IfModule>

然后,如果您使用的是 Nginx

location / {
  try_files $uri $uri/ /index.html;
}

仅此而已

有关更多信息,请访问此Link

答案 13 :(得分:0)

我也面临同样的问题。在路由 -> web.php 中添加此代码后,问题已解决。

   Route::get('/{vue_capture?}', function () {
    return view('admin.dashboard');
})->where('vue_capture', '[\/\w\.-]*');

将此路由重定向到您的父刀片视图。