说我有这个网页:http://ww.xyz.com/Product.aspx?CategoryId=1
如果CategoryId = 1的名称是“Dogs”,我想将URL转换为如下所示:http://ww.xyz.com/Products/Dogs
问题是如果类别名称包含外来(或对于URL无效)字符。如果CategoryId = 2的名称是“Göraäldre”,那么新的URL应该是什么?
逻辑上它应该是:http://ww.xyz.com/Products/Göra äldre
但它不起作用。
首先是因为空间(我可以很容易地用短划线取代)但是外国人物呢?在Asp.net中我可以使用URLEncode函数,它会给出类似这样的东西:http://ww.xyz.com/Products/G%c3%b6ra+%c3%a4ldre
但我不能说它比原始URL(http://ww.xyz.com/Product.aspx?CategoryId=2
)更好。
理想情况下,我想生成这个,但我怎么能自动执行此操作(即将外来字符转换为'安全'URL字符):http://ww.xyz.com/Products/Gora-aldre
。
我想出了以下两种扩展方法(asp.net/C#):
public static string RemoveAccent(this string txt)
{
byte[] bytes = System.Text.Encoding.GetEncoding("Cyrillic").GetBytes(txt);
return System.Text.Encoding.ASCII.GetString(bytes);
}
public static string Slugify(this string phrase)
{
string str = phrase.RemoveAccent().ToLower();
str = System.Text.RegularExpressions.Regex.Replace(str, @"[^a-z0-9\s-]", ""); // Remove all non valid chars
str = System.Text.RegularExpressions.Regex.Replace(str, @"\s+", " ").Trim(); // convert multiple spaces into one space
str = System.Text.RegularExpressions.Regex.Replace(str, @"\s", "-"); // //Replace spaces by dashes
return str;
}
这取决于您使用的语言和您要使用的技术。看一下Django source中的这段JavaScript代码,它完全符合您的需求。您可以轻松地将其移植到您选择的语言中。
这是Python slugify函数中使用的Django片段,它更短:
def slugify(value):
"""
Normalizes string, converts to lowercase, removes non-alpha characters,
and converts spaces to hyphens.
"""
import unicodedata
value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore')
value = unicode(re.sub('[^\w\s-]', '', value).strip().lower())
return re.sub('[-\s]+', '-', value)
我认为每种语言都有这个端口,因为这是一个常见的问题。只是谷歌的slugify +你的语言。
您可以向Products表添加一个新字段,其中包含每个产品的URL安全且唯一的名称。这可能最初是自动生成的(用最接近的安全等价物替换非安全字符 - gora-aldre
?)然后根据需要进行微调。
由于非安全字符的替换不是(总是)可逆的,所以在运行中做这种事情并不完全可行。
或者,您可以这样构建URL:
http://example.com/products/1234/safe-string
其中safe-string
即时创建,根据需要替换不安全的字符。数字1234
是产品密钥。您使用密钥查找产品,'safe-string'对用户和搜索引擎来说更多。
要记住两件事:
URL重写通常不会对搜索引擎产生积极影响(通常是负面影响) - 因此,只有当您知道对用户满意度产生可衡量的积极影响时才应该这样做(并相应地:使您的URL对用户有用) 。
如果你决定进行URL重写,你必须完美地删除技术细节。例如,您永远不应该有多个显示相同内容的唯一网址。确保使用UTF-8进行非ASCII内容的编码,使用内容中的转义链接,并通常在各种浏览器上进行测试,以确保按计划运行。如果这对您来说是陌生的,那么我强烈建议您暂时不进行URL重写。
FWIW一些搜索引擎方面的问题在 http://googlewebmastercentral.blogspot.com/2008/09/dynamic-urls-vs-static-urls.html
IMO的最佳方法是白名单字符,而不是试图寻找无效字符。但是,像é这样的重音字符相当常见(如果没有它们,你的URL会很奇怪),所以你可以先转换它们。
在PHP中你可以使用strtr
函数,但你应该能够根据你的需要在asp.net上修改它:
strtr(
'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûýýþÿŔŕ',
'aaaaaaaceeeeiiiidnoooooouuuuybsaaaaaaaceeeeiiiidnoooooouuuyybyrr'
);
现在这是你的过程:
由于您发布了标记为ASP.Net: 查看此站点 ,它包含示例代码,用替换(大多数)文本与变音符号(您称之为无效字符)及其基本字符。
正如Kris所提到的,在您的网址中使用唯一ID,就像这个网站一样。如果您无法控制提供给您的ID,则应创建一个包含唯一ID的转换表,以及外部唯一ID。这样,当外部ID发生变化时,您的内部引用也很好。与您的唯一ID一起,您可以存储“搜索和人工优化ID”,这个ID不是那么独特,但看起来不错。
维基百科经常在其URL中使用非latin1字符。没有理由(除了您的网络服务器不支持它们)您不应该使用这些URL。
然而;如果你必须避免这些字符,我发现用非- 变音符号 形式替换它们。阅读这些内容的大多数人可以(从上下文)告诉词应该是什么,即使已经删除了变音符号。