Flutter Web:SPA:打开图:动态分配og:image元标记 [英] Flutter Web: SPA: Open Graph: Dynamically assign og:image meta tags

查看:95
本文介绍了Flutter Web:SPA:打开图:动态分配og:image元标记的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试为爬虫创建动态的og:image标签,以捕获适当的缩略图.我有一个JS脚本生成适当的og:image url,但是搜寻器在搜索时似乎没有运行任何JS.有更好的方法吗?

Trying to create dynamic og:image tags for crawlers to catch appropriate thumbnails. I've got a JS script generating the appropriate og:image url, but the crawlers don't appear to run any JS when searching. Is there a better way to do this?

当前:

<head>
  <script>
    const queryString = window.location.href;
    const urlParams = new URLSearchParams(queryString);
    const uid = urlParams.get('uid')
    const pid = urlParams.get('pid')
    if (uid != null && pid != null)
      document.getElementById('urlThumb').content = `https://my.app/posts%2F${uid}%2F${pid}%2Furl_thumb.jpg?alt=media`;
  </script>
  <meta property="og:image" id='urlThumb' content="https://my.app/default%default.png?alt=media"/>

...

</head>

推荐答案

好,所以我能够以半黑客的方式实现这一目标.我修改了firebase.json以将"/post"路由路由到firebase云函数.您只需将路线源"添加到您要重新路由并添加要触发的Firebase云功能的名称.

ok, so I was able to achieve this in a semi-hack way. I modified firebase.json to route '/post' route to a firebase cloud function. You simple add the route "source" you want to reroute and add the name of the firebase cloud function you want to trigger.

    "rewrites": [
      {
        "source": "/post",
        "function": "prebuildPostPage"
      },
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]

我必须添加"express"包来处理https请求.在您的功能文件夹中运行"npm i express".然后我做了这两个功能(看起来有些奇怪):

I had to add the 'express' package to handle the https request. in your functions folder run 'npm i express'. Then I made these two functions (It looks a little bizarre):

const express = require('express');
const app = express();

app.get('/post', (req, res) => {
    console.log(req.query);
    const uid = req.query.uid;
    const pid = req.query.pid;
    console.log(`uid[${uid}], pid[${pid}]`);
    if (uid == null || pid == null)
        res.status(404).send("Post doesn't exist");
    res.send(`<!DOCTYPE html>
    <html>
    <head>
      <meta property="og:image" id='urlThumb' content="${`https://my.app/posts%2F${uid}%2F${pid}%2Furl_thumb.jpg?alt=media`}"/>
      <meta property="og:image:width" content="800">
      <meta property="og:image:height" content="600">
      
      //Rest is the same as index.js head.

    </head>
    <body id="app-container">
      //Same as index.js body
    </body>
    </html>
    `);
});

exports.prebuildPostPage = functions.https.onRequest(app);

这很适合使正确的手指接触到爬虫,但不幸的是,它会将人们引到了首页.没有布宜诺斯艾利斯.

This works great for getting the right thumb to the crawlers, unfortunately it sends people to the homepage. no bueno.

这是因为Flutter Web使用#"来管理页面的路由和历史记录.标签标签之后的所有内容都会在转发给我的云函数的url中忽略.

This is because Flutter Web uses a '#' to manage routing and history of pages. Everything after the hashtag is ignored in the url forwarded to my cloud function.

如此... hack的一部分...我不是我颤抖的Web应用程序main.dart文件,我必须检查给定的URL是否实际上是"my.app/post?uid=xxx&pid= xxx"格式.在这种情况下,我没有加载从首页开始的默认MyApp,而是创建了一个名为MyAppPost的第二个选项,该选项默认为带有提供的uid和pid数据的帖子屏幕.这可行,但是却弄乱了我的导航器系统.

SO... the hack part... I'n my flutter web app main.dart file I had to check if the given URL is in fact a "my.app/post?uid=xxx&pid=xxx" format. In which case instead of loading my default MyApp which starts at the homepage, I created a second option called MyAppPost which defaults to the post screen with the provided uid and pid data. This works, but it screws up my navigator system.

将继续尝试并改进此设置.

Will continue to try and improve this setup.

void main() {
  //Provider.debugCheckInvalidValueType = null;
  setupLocator();
  String url = window.location.href;
  String _uid;
  String _pid;
  bool isPost = false;
  print(url);
  if (url.contains('/post')) {
    _uid = getParam(url, 'uid', 28);
    _pid = getParam(url, 'pid', 20);
    if (_uid != null && _pid != null) isPost = true;
  }
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(
          create: (_) => PageManager(),
        ),
      ],
      child: isPost
          ? MyAppPost(
              uid: _uid,
              pid: _pid,
            )
          : MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'VESTIQ',
      navigatorKey: locator<NavigationService>().navigatorKey,
      onGenerateRoute: (rs) => generateRoute(rs, context),
      initialRoute: HomeRoute,
    );
  }
}

class MyAppPost extends StatelessWidget {
  final String uid;
  final String pid;

  const MyAppPost({Key key, this.uid, this.pid}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'VESTIQ',
      navigatorKey: locator<NavigationService>().navigatorKey,
      //onGenerateRoute: (rs) => generateRoute(rs, context),
      home: PostView(
        oid: uid,
        pid: pid,
      ),
    );
  }
}

工作中的导航器

void main() {
  setupLocator();
  String url = window.location.href;
  String _uid;
  String _pid;
  bool launchWebApp = false;
  if (url.contains('/post')) {
    _uid = getParam(url, 'uid', 28);
    _pid = getParam(url, 'pid', 20);
  }
  if (url.contains('/app')) launchWebApp = true;
  runApp(
    MyApp(
      uid: _uid,
      pid: _pid,
      launchWebApp: launchWebApp,
    ),
  );
}

class MyApp extends StatelessWidget {
  final String uid;
  final String pid;
  final bool launchWebApp;

  const MyApp({Key key, this.uid, this.pid, this.launchWebApp})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    bool isPostLink = (uid != null && pid != null);
    if (isPostLink) {
      urlPost = PostCard.fromPost(Post()
        ..updatePost(
          uid: uid,
          pid: pid,
        ));
    }
    Provider.of<Post>(context, listen: false).updatePost(uid: uid, pid: pid);
    return MaterialApp(
      title: 'VESTIQ',
      navigatorKey: locator<NavigationService>().navigatorKey,
      onGenerateRoute: (rs) => generateRoute(rs, context),
      initialRoute: launchWebApp
          ? AppRoute
          : isPostLink
              ? PostRoute
              : HomeRoute,
    );
  }
}

这篇关于Flutter Web:SPA:打开图:动态分配og:image元标记的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆