我在将网址中的电子邮件地址传递给symfony应用时遇到了一些问题。
网址看起来像
example.com/unsubscribe/email/me@example.com
除非删除句号,否则始终会生成sfError404Exception
。在做了一些谷歌搜索后,我看到的唯一解决方案是htaccess因为存在期间而绕过网址。但是,当我将建议的修复添加到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(example.com/index.php/unsubscribe/email/me@example.com
)中使用前端控制器时,它也会返回404。我已经尝试将转义版本直接放到地址栏中,例如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/me@example.com" (/).
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
答案 0 :(得分:10)
默认情况下,Symfony将.
和/
视为参数分隔符
这样可以很容易地匹配这样的URL:
/some/path/:param.:ext
但对电子邮件地址没有帮助。
幸运的是,您可以通过指定自己的模式来覆盖.
分隔符
只需将以下requirements
行添加到您的路由:
unsubscribeform:
url: /unsubscribe/email/:email
param: { module: subscribe, action: index }
requirements: { email: .+ }
需求中的.+
是匹配任何内容的正则表达式。 .
匹配任何字符,+
表示匹配一个或多个。
(在Symfony 1.4中测试)
答案 1 :(得分:3)
我不知道您在Symfony中做了什么,但可能有助于明确以下内容不是有效的网址:
example.com/unsubscribe/email/me@example.com
你几乎肯定想要的(所有浏览器都是如此!)是:
http://example.com/unsubscribe/email/me%40example.com
注意:@符号不安全,必须编码,。但符号是安全的(RFC1738)。如果你没有逃脱@符号,它几乎肯定会造成大麻烦(逃避。几乎肯定不会,但你不需要这样我不会)。
在没有转义的情况下会出现问题,因为@在传递身份验证参数时会被保留为分隔符(例如http://username:password@hostname.domain/url/)。如果@出现在URL中的域之后,某些URL解析器将确定您真正打算键入%40,但其他人不会。
您不应仅仅静态编码@符号,而应使用电子邮件地址上的PHP URL编码功能之一(例如“$ emailAddress = urlencode($emailAddress);”),以确保地址中的其他字符也能正确转义。不要试图将它留到以后或“在你工作之后”从一开始就这样做并保存自己和最终用户头疼! : - )
注意:有几种方法可以在PHP中对URL进行编码,因此您需要阅读urlencode()的文档页面,并将其与rawurlencode()等其他方法进行比较,以确保它是您真正想要的。
答案 2 :(得分:0)
您的问题不在于重写规则。考虑到Symfony正在抛出异常,那么请求正在向Symfony发送。
你可以发布异常的追溯吗?如果你有sf_logging_enabled,它应该记录一些非常有用的信息来调试路由。