Javascript Vue meta未获得更新

Javascript Vue meta未获得更新,javascript,laravel,vue.js,vuejs2,vue-meta,Javascript,Laravel,Vue.js,Vuejs2,Vue Meta,当我访问我的内部页面时,vue meta不会被新的页面值更新 代码 app.js import VueMeta from 'vue-meta' Vue.use(VueMeta, { refreshOnceOnNavigation: true }) App.vue(主要组件) post.vue(内部组件) 有什么想法吗? 更新 当我发表这个问题的时候,它是关于不更新的,然后在做了一些研究并使用我的代码之后,我意识到我的vue元得到了更新,但是,很晚,,它导致社交网络网站和SEO检查器无法

当我访问我的内部页面时,
vue meta
不会被新的页面值更新

代码
app.js

import VueMeta from 'vue-meta'
Vue.use(VueMeta, {
    refreshOnceOnNavigation: true
})
App.vue
(主要组件)

post.vue
(内部组件)

有什么想法吗?

更新 当我发表这个问题的时候,它是关于不更新的,然后在做了一些研究并使用我的代码之后,我意识到我的vue元得到了更新,但是,很晚,,它导致社交网络网站和SEO检查器无法正确检索我的URL

澄清
  • Vue meta得到更新,但很晚
  • 此延迟更新导致SEO无法通过共享和验证的时间链接呈现
  • My full meta tags code

    metaInfo() {
        return {
          title: this.post.name,
          meta: [
            {
              vmid: "keyword",
              name: "keyword",
              content: this.post.metas[0].tags,
            },
            {
              vmid: "description",
              name: "description",
              content: this.post.metas[0].description,
            },
            // Open Graph / Facebook
            { vmid: "og:type", name: "og:type", content: "website" },
            {
              vmid: "og:url",
              name: "og:url",
              content: process.env.MIX_APP_URL + this.$router.currentRoute.fullPath,
            },
            {
              vmid: "og:site_name",
              name: "og:site_name",
              content: `"${process.env.MIX_APP_NAME}"`,
            },
            {
              vmid: "og:title",
              name: "og:title",
              content: this.post.name,
            },
            {
              vmid: "og:description",
              name: "og:description",
              content: this.post.metas[0].description,
            },
            {
              vmid: "og:image",
              name: "og:image",
              content: this.post.imagebig,
            },
            //   Twitter
            {
              vmid: "twitter:card",
              name: "twitter:card",
              content: "summary",
            },
    
            {
              vmid: "twitter:author",
              name: "twitter:author",
              content: "@xxxxxx",
            },
            {
              vmid: "twitter:site",
              name: "twitter:site",
              content: "@xxxxxx",
            },
            {
              vmid: "twitter:creator",
              name: "twitter:creator",
              content: "@xxxxxx",
            },
            {
              vmid: "twitter:url",
              name: "twitter:url",
              content: process.env.MIX_APP_URL + this.$router.currentRoute.fullPath,
            },
            {
              vmid: "twitter:title",
              name: "twitter:title",
              content: this.post.name,
            },
            {
              vmid: "twitter:description",
              name: "twitter:description",
              content: this.post.metas[0].description,
            },
            {
              vmid: "twitter:image",
              name: "twitter:image",
              content: this.post.imagebig,
            },
          ],
        };
    },
    
    额外的
  • 最近我读到一篇文章,因为基于JavaScript社交媒体爬虫的vue meta(通常是vue)加载不会缓存它们,因此在FB或Twitter等中共享链接时,不可能看到我的链接详细信息

  • 建议的解决方案是使用Nuxt并在服务器端返回元数据

  • 问题

  • 我不确定上面的1是正确的,但这是可能的
  • 我的应用程序一般不使用Nuxt,但我只是安装了它的npm包,所以可能值得一试(正如我提到的,我从未使用过Nuxt,因此如果您的帮助解决方案是这样的话,如果您在回答中包含一些额外的细节,我将不胜感激)
  • 问题

    我不确定上面有多少是正确的,但我的应用程序可能会这样 通常不使用Nuxt,但我只是安装了它的npm包 这可能值得一试(正如我提到的,我从未使用过Nuxt,所以如果 这就是你的帮助解决方案如果你能 在你的答案中加入一些额外的细节)


    对您的问题的简短回答:您无法动态更改vue元标记,因为这需要服务器端呈现(nuxt)

    vue本身是客户端JS框架。当您构建时,您的
    index.html
    没有任何在执行时生成内容的纯内容JS。这同样适用于VueMeta。问题是,当您共享链接(FB、Twitter等)时,他们使用自己的机器人(基本上是爬虫)下载链接页面,并分析内容,而不在内部执行任何JS-所以是的,他们看不到VueMeta生成的任何元

    唯一的解决方案是在不执行JS的情况下交付包含所有重要信息的完全(或部分)预呈现页面

    这样做的一种方法是使用——你是对的,像Nuxt这样的框架就是这样使用的

    通常有两种口味:

    SSR-页面在客户端(或bot)请求时呈现。在大多数情况下,它需要运行节点服务器(因为Vue SSR是在JS中实现的)。最突出的例子是Nuxt.js

    SSG-服务器端生成。页面在构建时生成,包括所有HTML。加载到浏览器服务器时,返回HTML+所有JS/CSS,但加载时返回的是相同的Vue SPA。您不需要节点服务器,所以您可以在CDN或任何静态托管服务(如Netlify)上托管。Vue世界中的例子有Gridsome、VuePress和Nuxt也可以做到这一点

    注意:还有其他方法,例如使用或服务,如

    努克斯 如前所述,Nuxt很棒,但在应用程序的结构(基于文件的路由)、数据获取等方面非常固执己见。因此,切换到Nuxt可能意味着完全重写应用程序。除此之外,还需要运行节点服务器,这会产生自身的后果(托管)

    但是在我看来,您已经在使用server-Laravel了。因此,最好的办法可能是直接在Laravel中实现元渲染


    更新:似乎有可能进行Vue SSR

    您的假设是正确的。不久前,我也花了不少时间试图找到解决这个问题的办法。这是我在一天结束时想到的:

  • 对于那些运行JavaScript的爬虫程序,请继续使用
    vue meta
    (对吧?)
  • 实施服务器端解决方案(使用Laravel包)
  • 选项1应该很清楚,因为您已经有了类似的实现

    对于方案2,我的方法如下:

    • 我为我的Laravel申请挑选了一个包裹。它很容易安装和注册。我敢肯定,Laravel或其他框架和语言也有很多这样做的包

    • 我在捕获所有前端路由请求的路由文件(
      web.php
      (如果您使用的是Laravel))的末尾添加了此路由:

    IndexController
    中,我首先检查请求是否来自爬虫程序。如果是这样,我将应用相关的元标记。以下是一瞥:

    <?php
    
    declare(strict_types=1);
    
    namespace App\Http\Controllers;
    
    use Butschster\Head\Facades\Meta;
    use Butschster\Head\Packages\Entities\OpenGraphPackage;
    
    class IndexController extends Controller
    {
        const CRAWLERS = [
            'Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.96 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)',
            'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1 (compatible; AdsBot-Google-Mobile; +http://www.google.com/mobile/adsbot.html)',
            'Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Googlebot/2.1; +http://www.google.com/bot.html) Safari/537.36',
            'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)',
            'Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)',
            'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534+ (KHTML, like Gecko) BingPreview/1.0b',
            'Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)',
            'Googlebot-Image/1.0',
            'Mediapartners-Google',
            'facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)',
            'facebookexternalhit/1.1',
            'Twitterbot/1.0',
            'TelegramBot (like TwitterBot)',
        ];
    
        public function index()
        {
            if ($this->isACrawler()) {
                $this->applyMetaTags();
    
                return view('layouts.crawler');
            }
    
            return view('layouts.index');
        }
    
        public function isACrawler()
        {
            if (in_array(request()->userAgent(), self::CRAWLERS)) {
                return true;
            }
    
            return false;
        }
    
        private function applyMetaTags()
        {
            // Here you can check the request and apply the tags accordingly
            // e.g.
            //        preg_match("/articles\/[0-9]+/i", request()->path(), $url)
            //        preg_match("/[0-9]+/i", $url[0], $id);
            //        $article = Article::find($id);
            //
            //        Meta::prependTitle($article->name)
            //            ->addMeta('description', ['content' => $article->description]);
            //
            //        $og = new OpenGraphPackage('some_name');
            //
            //        $og->setType('Website')
            //            ->setSiteName('Your website')
            //            ->setTitle($article->name)
            //            ->setUrl(request()->fullUrl())
            //            ->setDescription($article->description);
            //
            //        if ($article->picture) {
            //            $og->addImage(asset($article->picture));
            //        }
            //
            //        Meta::registerPackage($og);
        }
    }
    
    
    注意事项:

    • 您需要自定义每个请求的元标记
    • 您需要维护爬虫的列表
    好处:

    • 它很简单,不需要对代码进行太多更改
    • 它向爬虫程序返回一个快速且轻量级的HTML
    • 您在后端拥有完全的控制权,只需稍作调整,就可以实现一个可维护的解决方案

    希望这有帮助!如果有不清楚的地方,请告诉我。

    您需要实现服务器端呈现来处理元标记。 因为几乎所有的爬虫程序都不支持javascript进程

    下面是PHP-Laravel的示例

    正如我们所知,vue.js是一个单页应用程序。所以每次它从一个根页面呈现时

    因此,对于laravel,我按原样配置了路由,每次返回带有标记数组的索引页并在视图中呈现该页时(索引页)

  • 拉维路由

  • 您可以将webpack配置为插入静态标记
    metaInfo() {
        return {
          title: this.post.name,
          meta: [
            {
              vmid: "keyword",
              name: "keyword",
              content: this.post.metas[0].tags,
            },
            {
              vmid: "description",
              name: "description",
              content: this.post.metas[0].description,
            },
            // Open Graph / Facebook
            { vmid: "og:type", name: "og:type", content: "website" },
            {
              vmid: "og:url",
              name: "og:url",
              content: process.env.MIX_APP_URL + this.$router.currentRoute.fullPath,
            },
            {
              vmid: "og:site_name",
              name: "og:site_name",
              content: `"${process.env.MIX_APP_NAME}"`,
            },
            {
              vmid: "og:title",
              name: "og:title",
              content: this.post.name,
            },
            {
              vmid: "og:description",
              name: "og:description",
              content: this.post.metas[0].description,
            },
            {
              vmid: "og:image",
              name: "og:image",
              content: this.post.imagebig,
            },
            //   Twitter
            {
              vmid: "twitter:card",
              name: "twitter:card",
              content: "summary",
            },
    
            {
              vmid: "twitter:author",
              name: "twitter:author",
              content: "@xxxxxx",
            },
            {
              vmid: "twitter:site",
              name: "twitter:site",
              content: "@xxxxxx",
            },
            {
              vmid: "twitter:creator",
              name: "twitter:creator",
              content: "@xxxxxx",
            },
            {
              vmid: "twitter:url",
              name: "twitter:url",
              content: process.env.MIX_APP_URL + this.$router.currentRoute.fullPath,
            },
            {
              vmid: "twitter:title",
              name: "twitter:title",
              content: this.post.name,
            },
            {
              vmid: "twitter:description",
              name: "twitter:description",
              content: this.post.metas[0].description,
            },
            {
              vmid: "twitter:image",
              name: "twitter:image",
              content: this.post.imagebig,
            },
          ],
        };
    },
    
    Route::get('/{any}', 'IndexController@index')->where('any', '.*');
    
    <?php
    
    declare(strict_types=1);
    
    namespace App\Http\Controllers;
    
    use Butschster\Head\Facades\Meta;
    use Butschster\Head\Packages\Entities\OpenGraphPackage;
    
    class IndexController extends Controller
    {
        const CRAWLERS = [
            'Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.96 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)',
            'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1 (compatible; AdsBot-Google-Mobile; +http://www.google.com/mobile/adsbot.html)',
            'Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Googlebot/2.1; +http://www.google.com/bot.html) Safari/537.36',
            'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)',
            'Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)',
            'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534+ (KHTML, like Gecko) BingPreview/1.0b',
            'Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)',
            'Googlebot-Image/1.0',
            'Mediapartners-Google',
            'facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)',
            'facebookexternalhit/1.1',
            'Twitterbot/1.0',
            'TelegramBot (like TwitterBot)',
        ];
    
        public function index()
        {
            if ($this->isACrawler()) {
                $this->applyMetaTags();
    
                return view('layouts.crawler');
            }
    
            return view('layouts.index');
        }
    
        public function isACrawler()
        {
            if (in_array(request()->userAgent(), self::CRAWLERS)) {
                return true;
            }
    
            return false;
        }
    
        private function applyMetaTags()
        {
            // Here you can check the request and apply the tags accordingly
            // e.g.
            //        preg_match("/articles\/[0-9]+/i", request()->path(), $url)
            //        preg_match("/[0-9]+/i", $url[0], $id);
            //        $article = Article::find($id);
            //
            //        Meta::prependTitle($article->name)
            //            ->addMeta('description', ['content' => $article->description]);
            //
            //        $og = new OpenGraphPackage('some_name');
            //
            //        $og->setType('Website')
            //            ->setSiteName('Your website')
            //            ->setTitle($article->name)
            //            ->setUrl(request()->fullUrl())
            //            ->setDescription($article->description);
            //
            //        if ($article->picture) {
            //            $og->addImage(asset($article->picture));
            //        }
            //
            //        Meta::registerPackage($og);
        }
    }
    
    
    <!DOCTYPE html>
    <html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
        <head>
            @meta_tags
    
            <link rel="shortcut icon" href="{{ asset('favicon.ico') }}">
        </head>
    </html>
    
    
    // vue.config.js
    module.exports = {
        configureWebpack: {
            output: {
                publicPath: '/static/'
            },
    
            plugins: [
              new HtmlWebpackPlugin(),
              new HtmlWebpackTagsPlugin(
                {tags: ['a.js', 'b.css'], append: true },
                {metas: [{
                    path: 'asset/path',
                    attributes: {
                        name: 'the-meta-name'
                        }}]
                })
            ]
        }
    }