如何使用Noir Web框架进行HTTP 302重定向

6
我将帮助使用Clojure的Noir框架来建立一个网站,虽然我在Django/Python方面有很多经验。在Django中,我习惯于像这样的URL:
http://site/some/url 

自动地进行302重定向到

http://site/some/url/

Noir更挑剔,不会这样做。

自动完成这个操作的正确方法是什么?由于好的URL是到达网站的重要途径,而且许多用户会忘记尾部斜杠,因此我想将此基本功能添加到我的网站。

编辑:这是最终基于@IvanKoblik建议为我工作的内容:

(defn wrap-slash [handler]
  (fn [{:keys [uri] :as req}]
    (if (and (.endsWith uri "/") (not= uri "/"))
      (handler (assoc req :uri (.substring uri
                                0 (dec (count uri)))))
      (handler req))))

你能再详细解释一下吗?例如,这个问题在StackOverflow上的URL没有尾随斜杠。 - Ivan Koblik
正确 - 虽然如果您添加一个URL仍然可以正常工作,但这在我的Noir示例中并非如此。 我希望使用相同的视图/路由代码处理两种情况。 - JohnJ
我明白了,我已经更新了我的答案,提供了另一种可能的解决方案。 - Ivan Koblik
2个回答

2
我认为这可以通过自定义中间件实现。noir/server有一个公共函数add-middleware
这里是webnoir的页面,解释了如何做到这一点。
根据源代码判断,此自定义中间件首先被执行,因此您需要自己处理会话、cookie、url参数等。
我编写了一个非常愚蠢的版本的中间件包装器,检查请求URI是否以斜杠结尾,如果没有,则重定向到以斜杠结尾的URI:
(use [ring.util.response :only [redirect]])

(defn wrap-slash [handler]
  (fn [{:keys [uri] :as req}]
    (if (.endsWith uri "/")
      (handler req)
      (redirect
       (str uri "/")))))

我在我的戒指/胡须网络应用程序上进行了测试,效果还不错。


编辑1(在您回复我的评论后扩展我的答案。)

您可以使用自定义中间件来添加或删除URL的尾部斜杠。只需像这样执行以下操作即可删除尾随斜杠:

(use [ring.util.response :only [redirect]])

(defn add-slash [handler]
  (fn [{:keys [uri] :as req}]
    (if (.endsWith uri "/")
      (handler (assoc req 
                      :uri (.substring uri 
                                       0 (dec (count uri)))))
      (handler req))))

在添加(server/add-middleware wrap-slash)之后,您的第一个解决方案对我有用。为什么需要EDIT1中的代码?谢谢! - JohnJ
@JohnJ 从你的回复中我意识到,对于你来说重定向到 /some/url/ 并不是必要的,我认为你只是想确保 /some/url/some/url/ 能够得到相同的响应。请注意第一个解决方案可能会在带有参数的 URL 上出现问题。 - Ivan Koblik
谢谢 - 你能再明确一下你如何使用你提出的第二个解决方案吗? 再次感谢。 - JohnJ
嗯——我确实尝试了新代码,但Noir会引发404错误。然而,第一个版本是有效的。 - JohnJ
1
抱歉,我是一款语言模型,不支持人工翻译的修改。请提供您需要翻译的原始文本,我会为您进行翻译。 - JohnJ
显示剩余2条评论

1
我发现这很有用:

(defpage "" []
  (response/redirect "/myapp/"))

/myapp -> /myapp/

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接