Symfony:电子邮件地址作为请求参数

问题描述 投票:0回答:4

我在将 url 中的电子邮件地址传递到 symfony 应用程序时遇到一些问题。

网址看起来像

example.com/unsubscribe/email/[email protected]

它总是会导致

sfError404Exception
,除非删除句号。在进行了一些谷歌搜索后,我见过的唯一解决方案是 htaccess 由于存在句点而绕过了 url。但是,当我将建议的修复添加到 htaccess 时,如下所示:

# we skip all files with .something
RewriteCond %{REQUEST_URI} \..+$
RewriteCond %{REQUEST_URI} !@.+    #skip email address
RewriteCond %{REQUEST_URI} \.epl$
RewriteCond %{REQUEST_URI} !\.html$ 
RewriteCond %{REQUEST_URI} !\.rhtml$
RewriteRule .* - [L]

我得到了相同的404。当我直接在url中使用前端控制器时,它也会返回404(

example.com/index.php/unsubscribe/email/[email protected]
)。我尝试过将转义版本直接放入地址栏,例如
example.com/unsubscribe/me%40example%2Ecom
并且这有效,但仅限于 Firefox,其他地方都没有。

我已经花了大约 2 个小时在论坛上回答谷歌搜索,此时我已经没有想法了。

有什么想法吗?

谢谢。

更新:这是routing.yml的相关部分:

unsubscribeform:
  url:  /unsubscribe/email/:email
  param: { module: subscribe, action: index }

更新:堆栈跟踪......看起来它没有获得任何路线信息来继续我

404 | Not Found | sfError404Exception
Empty module and/or action after parsing the URL "/unsubscribe/email/[email protected]" (/).
stack trace

1. at ()
  in SF_SYMFONY_LIB_DIR/controller/sfFrontWebController.class.php line 44 ...
          41.
          42.       if (empty($moduleName) || empty($actionName))
          43.       {
          44.         throw new sfError404Exception(sprintf('Empty module and/or action after parsing the URL "%s" (%s/%s).', $request->getPathInfo(), $moduleName, $actionName));
          45.       }
          46.
          47.       // make the first request
2. at sfFrontWebController->dispatch()
  in SF_SYMFONY_LIB_DIR/util/sfContext.class.php line 159 ...
         156.    */
         157.   public function dispatch()
         158.   {
         159.     $this->getController()->dispatch();
         160.   }
         161.
         162.   /**
3. at sfContext->dispatch()
  in /home/web/htdocs/index.php line 10 ...
           7. require_once(SF_ROOT_DIR.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'ProjectConfiguration.class.php');
           8.
           9. $configuration = ProjectConfiguration::getApplicationConfiguration(SF_APP, SF_ENVIRONMENT, SF_DEBUG);
          10. sfContext::createInstance($configuration)->dispatch();

11.

php .htaccess url-rewriting symfony1
4个回答
10
投票

默认情况下,Symfony 将

.
/
视为参数分隔符。
这使得像这样匹配 url 变得非常容易:

/some/path/:param.:ext

但对电子邮件地址没有帮助。

幸运的是,您可以通过指定自己的模式来覆盖

.
分隔符。
只需将下面的
requirements
行添加到您的路由中:

unsubscribeform:
  url:  /unsubscribe/email/:email
  param: { module: subscribe, action: index }
  requirements: { email: .+ }

需求中的

.+
是匹配任何内容的正则表达式。
.
匹配任意字符,
+
表示匹配一个或多个。

(在 Symfony 1.4 中测试)


3
投票

我不知道你在 Symfony 中做什么,但澄清以下不是有效的 URL 可能会有所帮助:

example.com/unsubscribe/email/[email protected]

您几乎肯定想要的(这对于所有浏览器都是如此!)是:

http://example.com/unsubscribe/email/me%40example.com

注意:@符号不安全,必须进行编码,.然而符号是安全的(RFC1738)。如果你不转义 @ 符号,它几乎肯定会造成大麻烦,所以(转义 . 几乎肯定不会,但你不需要,所以我不会)。

不转义会出现问题,因为@在传递身份验证参数时被保留作为分隔符(例如http://username:[email protected]/url/)。如果 @ 出现在 URL 中的域后面,一些 URL 解析器会判断出您确实要输入 %40,但其他解析器则不会。

不仅仅是静态编码 @ 符号,您应该在电子邮件地址上使用 PHP 的 URL 编码函数之一(例如“$emailAddress = urlencode($emailAddress);”)以确保地址中的其他字符也能正确转义。不要试图把这件事留到以后或“在你让它工作之后”,从一开始就做,这样可以让你自己和最终用户感到头痛! :-)

注意:在 PHP 中对 URL 进行编码的方法有多种,因此您需要通读 urlencode() 的文档页面,并将其与 rawurlencode() 等其他方法进行比较,以确保它是您真正想要的。


0
投票

您的问题不在于重写规则。考虑到 Symfony 抛出异常,然后请求将发送到 Symfony。

您可以发布异常的回溯吗?如果您启用了 sf_logging_enabled 它应该记录一些非常有用的信息以调试路由。


0
投票

我找到的这个问题的解决方案是将数据编码为 Base64。

Base64 字符串是 url 安全的,这就是它们可用于在数据 URL 中对数据进行编码的原因。

let safeDataURL = encodeToBase64(email)
© www.soinside.com 2019 - 2024. All rights reserved.