问题描述
尝试为爬虫创建动态的og:image标签,以捕获适当的缩略图。我有一个JS脚本生成适当的og:image url,但是搜寻器在搜索时似乎没有运行任何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>
解决方法
好的,所以我能够以半黑客的方式实现这一目标。我修改了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);
这很适合使正确的手指接触到爬虫,不幸的是,它会将人们引到了首页。没有布宜诺斯艾利斯。
这是因为Flutter Web使用“#”来管理页面的路由和历史记录。标签标签之后的所有内容都会在转发给我的云函数的url中忽略。
所以... hack的一部分...我是我颤抖的Web应用程序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',//onGenerateRoute: (rs) => generateRoute(rs,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,20);
}
if (url.contains('/app')) launchWebApp = true;
runApp(
MyApp(
uid: _uid,launchWebApp: launchWebApp,);
}
class MyApp extends StatelessWidget {
final String uid;
final String pid;
final bool launchWebApp;
const MyApp({Key key,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,));
}
Provider.of<Post>(context,listen: false).updatePost(uid: uid,pid: pid);
return MaterialApp(
title: 'VESTIQ',initialRoute: launchWebApp
? AppRoute
: isPostLink
? PostRoute
: HomeRoute,);
}
}