【问题标题】:Flutter Web: SPA: Open Graph: Dynamically assign og:image meta tagsFlutter Web: SPA: Open Graph: 动态分配 og:image 元标签
【发布时间】:2020-12-01 11:47:05
【问题描述】:

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

目前:

<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>

【问题讨论】:

    标签: javascript html single-page-application facebook-opengraph flutter-web


    【解决方案1】:

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

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

    我必须添加“express”包来处理 https 请求。在您的函数文件夹中运行“npm i express”。然后我做了这两个函数(看起来有点怪):

    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);
    
    

    这非常适合让爬虫获得正确的拇指,不幸的是它会将人们带到主页。没有bueno。

    这是因为 Flutter Web 使用“#”来管理页面的路由和历史记录。在转发到我的云函数的 url 中,主题标签之后的所有内容都会被忽略。

    所以...黑客部分...我在我的颤振网络应用程序 main.dart 文件中,我必须检查给定的 URL 是否实际上是“my.app/post?uid=xxx&pid=xxx”格式.在这种情况下,我没有加载从主页开始的默认 MyApp,而是创建了第二个选项 MyAppPost,它默认为带有提供的 uid 和 pid 数据的帖子屏幕。这可行,但它搞砸了我的导航系统。

    将继续尝试改进此设置。

    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,
        );
      }
    }
    

    【讨论】:

    • 请及时更新,我正在关注这个问题,因为我面临同样的问题。
    • 导航系统最终工作正常。但是,URL 有点难看。它变成“my.app/post?uid=xxx&pid=xxx/#/[navigator page]”。可能有一种方法可以修改现有的 URL,但我没有需要。我只是在建立一个 MVP。这仍然是我正在使用的解决方案。
    • 非常感谢您的更新!我会尝试一下,看看它会导致什么。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-15
    • 2017-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-02
    相关资源
    最近更新 更多