我使用MongoDB/mongoose使用以下架构存储博客文章:
PostSchema = mongoose.Schema({
title: {type: String},
body: {type: String}
});
现在,我的帖子网址如下所示:http://www.example.local/posts/571f78d077b4454bafcfcced
我希望我的帖子中包含如下内容:http://www.example.local/posts/571f78d077b4454bafcfcced/how-to-make-and-store-slug-for-title
所以我的问题是:http://www.example.local/posts/571f78d077b4454bafcfcced
重定向到http://www.example.local/posts/571f78d077b4454bafcfcced/how-to-make-and-store-slug-for-title
(nodejs,nginx,客户端)。 谢谢!
EIDT:我还发现,在StackOverflow Database viwer中,ID为503429的问题可以存储非标题标题。那么,这是否意味着每次提出问题时,SO都会计算?
最佳答案
1.我应该一次生成段子并存储在PostModel模式中,还是在每个显示的帖子中生成?
两种方法均有效且具有优点:
在这两种情况下,您都必须选择一种模式并定义一个算法以生成与所选模式匹配的子弹。
我个人几乎总是选择将段塞存储在数据库中,这允许您为特定帖子指定段塞。您可能永远不需要这样做,但是如果案子已经解决,您就已经准备好了。
例如,如果对于特定帖子,所生成的段符将是
awesome-post
,而您希望它是best-awesome-post
,那么如果段符存储在数据库中,则可以轻松实现,否则,您必须针对每个“特殊段”调整算法”案例,这将成为类似多个案例的噩梦。我认为还有一点要加以存储:发布文章后,该条将成为该文章的永久链接的一部分,应视为不可变的。如果在这种情况下可以避免多次生成不可变的数据,我不是 super 忠实的粉丝。
2.如何为非ASCII字符基于标题(哪些现有节点模块可解决此任务)生成段?
就像您说的那样,存在多个节点模块,以基于一个或多个字段(例如标题)生成子段,有些甚至与mongoose-url-slugs集成到MongoDB/Mongoose中。
在大多数子词中,重音字符会转换为非重音字符,所有内容都将转换为小写字母,删除标点符号,并使用
-
替换空格等。关于问题的ASCII部分,例如,如果您看一下mongoose-url-slugs的代码,则在生成段时,它们会调用removeDiacritics函数,该函数将去除这些特殊字符,并用对段友好的等效字符替换它们。
我能想到的一个需要特殊处理才能正确处理的示例是德语中的“road”一词:“Straße”。
该函数将识别Eszett字符(
\u00DF
)并将其替换为字母“s”。如果要向前迈进,则应使用处理unicode和utf-8的slug模块(例如slug),该模块符合有关统一资源标识符(URI)的RFC 3986的要求。
它将诸如
i ♥ my title
之类的标题转换为i-love-my-title
等。3.应该使用哪个位置将查询从
http://www.example.local/posts/571f78d077b4454bafcfcced
重定向到http://www.example.local/posts/571f78d077b4454bafcfcced/how-to-make-and-store-slug-for-title
(nodejs,nginx,客户端)。 如果您出于上述原因在数据库中存储了Slug,则应仅生成一次Slug,然后将其保存在数据库中。此时,在服务器端或客户端上不再发生任何重新生成。
在客户端上显示链接时,您将始终安全地使用以前生成的段,例如
http://www.example.local/posts/571f78d077b4454bafcfcced/how-to-make-and-store-slug-for-title
来按照所需的模式显示链接。如果客户端使用没有slug或部分slug之类的url(如
http://www.example.local/posts/571f78d077b4454bafcfcced/how-to-make
)重定向到带有完整slug的正确url,在一个很好的示例中,针对此特定问题的Stack Overflow,他们只是将301重定向发送到正确的网址。他们正在处理服务器上的这些特殊情况,因为服务器上的应用程序是唯一有权处理此问题的应用程序(如果您要在数据库中保存数据块的话)。您的应用程序知道特定帖子在数据库中的正确位置,因此如果未指定该位置或仅部分位置(在应用程序中很容易检测到),则可以安全地触发301重定向到具有正确URL的正确URL鼻涕虫,像
http://www.example.local/posts/571f78d077b4454bafcfcced/how-to-make-and-store-slug-for-title
。您应该在Node应用程序中处理这些情况(假设您使用的是您在问题中提到的Node),并在需要时重定向到正确的URL。
例如:
res.writeHead(301, { "Location": `http://www.example.local/posts/${postId}/${postSlug}` });
由于可以通过多个URL访问相似的内容,因此,您还应该使用规范链接元素来指定“规范” URL,搜索引擎应使用该URL以例如避免重复的内容问题。
<link rel="canonical" href="http://www.example.local/posts/571f78d077b4454bafcfcced/how-to-make-and-store-slug-for-title">
关于您对Stack Exchange Data Explorer的编辑,我认为他们从结果中省略了该字段,因为它并不是那么重要。根据a comment from Nick Craver, Software Developer and Systems Administrator for Stack Exchange的说法,他们确实是在检查数据库中已标记的标题是否与查询中的标题匹配,如果不匹配,则将它们重定向。
在网址中编辑有关俄语字符的内容:
例如,如果您想保留俄语字符,没问题,只要您跟上utf-8。您的链接示例显示俄语字符,但在URL背后是“百分比编码”或“URL编码”,您可以通过右键单击浏览器中的链接,选择“检查”来自己检查URL,然后您会看到该URL实际上类似于
http://ru.stackoverflow.com/questions/456697/genymotion-%D0%BE%D1%88%D0%B8%D0%B1%D0%BA%D0%B0-%D0%BF%D1%80%D0%B8-%D1%81%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B8-%D0%B2%D0%B8%D1%80%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE-%D1%83%D1%81%D1%82%D1%80%D0%BE%D0%B9%D1%81%D1%82%D0%B2%D0%B0
。您的浏览器知道它已进行url编码,并用俄语字符正确显示。当然,您可以使用Node.js模块甚至 native Javascript方法对所需的所有URL进行url编码。
如果您也对SEO和搜索引擎感到疑惑,例如Google:“我们通常可以跟上UTF-8编码的URL,我们通常会在搜索结果中向用户显示它们(但是使用URL链接到您的服务器)正确地逃脱了)”,因此完全没有问题。
大多数“slugifier”模块都会删除这些字符,因此,如果您实际上想保留它们,则必须使用更特定的内容,例如arSlugify:
var ars = require('arslugify');
var title = 'genymotion ошибка при создании виртуального устройства';
var slug = ars(title);
var url = 'www.example.local/posts/571f78d077b4454bafcfcced/' + slug;
var encodedUrl = encodeURIComponent(url);
console.log(url);
// www.example.local/posts/571f78d077b4454bafcfcced/genymotion-ошибка-при-создании-виртуального-устройства
console.log(encodedUrl);
// www.example.local%2Fposts%2F571f78d077b4454bafcfcced%2Fgenymotion-%D0%BE%D1%88%D0%B8%D0%B1%D0%BA%D0%B0-%D0%BF%D1%80%D0%B8-%D1%81%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B8-%D0%B2%D0%B8%D1%80%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE-%D1%83%D1%81%D1%82%D1%80%D0%BE%D0%B9%D1%81%D1%82%D0%B2%D0%B0
关于node.js - 如何制作和存储帖子标题的子弹?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37970263/