Php Silex中的内部转发,无需向浏览器发送301/302
我正在使用Silex的内部转发将公共URL映射到内部URL,即使用Php Silex中的内部转发,无需向浏览器发送301/302,php,symfony,silex,Php,Symfony,Silex,我正在使用Silex的内部转发将公共URL映射到内部URL,即使用 $subRequest = Request::create( $redirect, $method, [], // params $request->cookies->all(), $request->files->all(), $request->server->all() ); if ($request->getSession(
$subRequest = Request::create(
$redirect,
$method,
[], // params
$request->cookies->all(),
$request->files->all(),
$request->server->all()
);
if ($request->getSession())
{
$subRequest->setSession($request->getSession());
}
return $app->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true);
然而,在Chrome的检查工具中,这将显示为结果页面的301,然后该页面将提供结果。这是“设计的”,因为它代表了一个有趣的安全问题吗?有没有办法绕过这个限制
虽然我不能为其他东西发布代码,但要点是
// controller provider
$controller_factory->match('/something_else/{param}', function(...) {
include 'path/to/some/file';
});
及
该文件中没有重定向响应
编辑I在上述示例中过度简化。实际上,/something
是一个随机字符串(即/abcdefghijklmnopqrstuvwxyz
,它映射到许多内部路由之一(->/something\u other,->/something\u other\u 2,->等).不,我不这么认为。我相信是您的其他控制器不喜欢子请求并返回重定向响应,而您的其他控制器无条件返回浏览器
它可以是任何东西。Silex是一个微框架,这意味着可以用数百种不同的方式实现,在没有看到实际代码的情况下,几乎不可能给出任何建议。这是它带来的灵活性的另一面。它可能是重定向UrlMatcher
,或者是控制器、路由器、包含的文件等中的任何东西ror处理程序或中间件,其结果是重定向响应
考虑这个更加简单的单脚本应用程序示例:
<?php
// web/index.php
require_once __DIR__.'/../vendor/autoload.php';
$app = new Silex\Application();
$app->get(
'/the-only-functional',
function() use ($app) {
return new \Symfony\Component\HttpFoundation\Response(
$app['request']->get('q')
);
}
);
$app->get(
'/{whatever}',
function($whatever) use ($app) {
$subRequest = \Symfony\Component\HttpFoundation\Request::create(
'/the-only-functional',
'GET',
['q'=>$whatever]
);
$response = $app->handle($subRequest);
if (200 != $response->getStatusCode()) {
throw new \Exception(
"Aha, that's where the problem lies"
. $response->getStatusCode() . ":"
. $response->getContent()
);
}
return $response;
}
)->value('whatever', 'nothing');
$app->run();
您可以尝试不同的排列方式:
curl -v http://localhost:8081/
curl -v http://localhost:8081/blah-blah
curl -v http://localhost:8081/the-only-functional?q=direct
curl -v http://localhost:8081/?q=this+example+does+not+forward+query+string
你总是得到200个回复
不幸的是,在不共享代码的情况下,您只能自己调试应用程序。唯一明智的建议是在返回子响应之前分析子响应,并可能记录回溯以定位问题。您可以查看子请求:
解决这个问题的方法是使用单个字符进行修复:/
根据以下定义:
$controller_factory->match('/something_else/{param}/', function($app, $param) { ... });
$controller_factory->match('/something', function($app) {
// do the redirect to /something_else/{param}
$redirect = '/something_else/hello';
...
});
你能发现它吗?事实证明,Symfony智能地将路由转发到带有斜杠的路由,而没有将带有斜杠的路由匹配到带有斜杠的路由。我的问题是,我“正确”地解析了随机字符字符串中的/something\u else/something
(如果没有找到,请参阅我的编辑),但它不正确,因为它应该解析为/something\u else/something/
(注意后面的斜杠)你能给我们看一下/something\u其他
路由的控制器吗?@mTorres虽然我不能在控制器中共享代码,但我已经编辑了我的原始帖子,包括一个要点。如果还不够,请让我知道。只需调用其他路由调用的方法。我不想在内部重新实现整个控制器架构e这个方法。我过度简化了这个问题,/something
实际上是一个随机字符串,它被解析成一个实际的路由,这可能是许多选项之一。很酷,谢谢。我真的很感激。我会看一看并让你知道。如果你看第一个代码示例,我就是这么做的。
curl -v http://localhost:8081/
curl -v http://localhost:8081/blah-blah
curl -v http://localhost:8081/the-only-functional?q=direct
curl -v http://localhost:8081/?q=this+example+does+not+forward+query+string
use Silex\Application;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\HttpKernelInterface;
$app->get('/something', function (Application $app, Request $request) {
$subRequest = Request::create('/something_else', ...);
$response = $app->handle($subRequest, HttpKernelInterface::SUB_REQUEST, false);
return $response;
});
$controller_factory->match('/something_else/{param}/', function($app, $param) { ... });
$controller_factory->match('/something', function($app) {
// do the redirect to /something_else/{param}
$redirect = '/something_else/hello';
...
});