如果 URL 与 slug 不匹配,则规范链接和 301 重定向

Posted

技术标签:

【中文标题】如果 URL 与 slug 不匹配,则规范链接和 301 重定向【英文标题】:Canonical links and 301 Redirect if URL doesn't match slug 【发布时间】:2011-06-14 20:03:56 【问题描述】:

我正在尝试在 django/python 中实现类似于堆栈溢出的 URL 方案。

例如pk 与标题的 slug 一起存储在 URL 中,因此对于这个问题(id #4787731),URL 是

https://***.com/questions/4787731/canonical-links-and-301-redirect-if-url-doesnt-match-slug

如果我稍后更改标题(或只是在 url 中添加一些随机的杂物),那么网站仍然会知道我在寻找哪个问题(通过 ID),并将 301 重定向到正确的 URL - 例如试试看。

https://***.com/questions/4787731/canonical-links-MODIFIED-URL

所以

在我的页面中包含规范链接的最佳方式是什么,例如

(我可以使用 get_absolute_url)

识别当前 URL 与规范链接不匹配并发出 301 的最佳方法是什么?

注意 - 这个问题很相似,但只针对generating the slug on the fly or statically.的情况

【问题讨论】:

如果您仍然打算做 301,那么规范标签的用途是什么? 好问题,这正是 SO 所做的,涵盖了我怀疑的所有基础。 相关:Redirect from Generic View DetailView in Django 【参考方案1】:

1:如果有 301,我认为使用规范标签没有意​​义。

让我们想象一个场景,您将 URL 从 /q/111/hello-world 更改为 /q/111/foobar。引擎不会假设这两者是相等的,除非他们访问带有指向/q/111/foobar 的规范标签的原始网址(它不会,因为它现在是 301,切断页面之间关系的任何证据)。

2:我会直接做。定义一个非唯一的 slug 字段并与您的详细视图中捕获的 URL 进行比较。

# models
class MyModel(models.Model):
    # ...
    non_unique_slug = models.SlugField()

    def get_absolute_url(self):
        return "/questions/%s/%s" % (self.id, self.non_unique_slug)


# urls
    r'^questions/(?P<id>\d+)/(?P<slug>[\w-]+)/$' 

# views
def my_view(request, id, slug):
    page = Page.objects.get(id=id)
    if not slug == page.slug:
        return http.HttpResponsePermanentRedirect(page.get_absolute_url())

    # render page
    return direct_to_template(request, "foobar.html", 'page': page)

【讨论】:

【参考方案2】:

我按照 Yuji 的有用说明进行操作,但发现您需要使用 HttpResponsePermanentRedirect 对象来获得永久 301 而不是临时 302。

https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpResponsePermanentRedirect

【讨论】:

以上是关于如果 URL 与 slug 不匹配,则规范链接和 301 重定向的主要内容,如果未能解决你的问题,请参考以下文章

Javascript:匹配 URL 的 slug

如果与提供的 id 匹配,如何从对象数组中获取 slug 值?

Next.js 动态路由错误:提供的路径 `page-name` 与页面不匹配:`/[slug]`

如何创建 URL slug 扩展?

自定义 Django SlugField 验证会破坏 URL 匹配

如果条件不匹配,则重写规则