【问题标题】:Redirect php while keeping URL在保留 URL 的同时重定向 php
【发布时间】:2021-03-30 05:46:41
【问题描述】:

我正在尝试以一种非常常见的方法重定向 URL,但是,我无法弄清楚这一点。我已经阅读了一篇又一篇文章,但无法取得任何进展。我只是想在 php 中将诸如“domain.com/xx/xxxxxxxxxx”之类的 URL 重定向到“/index.php?first=xx&last=xxxxxxxxxx”。我尝试了几个 apache mod_rewrites 并且可以让 URL 在浏览器中保持不变,但是当我查看 index.php 中的 $_SERVER['REQUEST_URI'] 时,它没有按预期显示。相反,它显示的是输入的 URI,而不是重写。它还总是添加 URL 的“xx”部分。比如:

URL: domain.com/ab/1234567890
PHP: ab/1234567890
     ab/include/file.css
     ab/include/another.css

Getting: $_SERVER['REQUEST_URI'] = domain.com/ab/1234567890
Desired: $_SERVER['REQUEST_URI'] = domain.com/index.php?first=ab&last=1234567890

没有'ab'目录,应该是寻找'include/file.css'之类的文件。

以下是我尝试过的一些重定向:

 RewriteRule ^([a-zA-Z0-9/]+)$ index.php?first=$1

 RewriteCond %{QUERY_STRING} /([a-z][a-z])/([a-zA-Z0-9]+)
 RewriteRule ^/([a-z][a-z])/([a-zA-Z0-9]+)$ index.php?first=$1&last=$2 [L]

 RewriteCond   %{QUERY_STRING}           ^[a-z][a-z]/[a-zA-Z0-9]$
 RewriteRule   ^[a-z][a-z]/[a-zA-Z0-9]+$         index.php      [L,R=301]

我尝试了很多其他方法,但我尝试的任何方法似乎都不起作用。也许是因为我只是不熟悉 apache 重定向以及它如何与 PHP 交互。我擅长 PHP,只是不擅长 apache,因此这可能是我不知道要查找的术语的情况......

任何帮助将不胜感激!

更新

我当前的 apache 配置是:

RewriteEngine On
RewriteRule ^[a-z][a-z]/([a-z/]+.css)$ $1   [L]
RewriteRule ([a-z][a-z])/([a-zA-Z0-9]+) index.php?first=$1&second=$2    [L]

我尝试过切换订单,但这似乎没有任何区别。如果我在 PHP 中检查 $_SERVER['QUERY_STRING'] 变量值,它确实为浏览器中的原始 URL 正确格式化:

Browser: domain.com/ab/0123456789
$_SERVER['QUERY_STRING']: first=ab&second=0123456789

但是,对于页面请求的所有外部文件,这些文件没有被正确重定向,并且 PHP 脚本输出了错误的值:

Browser: domain.com/ab/include/style.css
$_SERVER['QUERY_STRING']: first=ab&second=include

这应该报告为:

$_SERVER['QUERY_STRING']: include/style.css

似乎由于某种原因没有为 css 文件选择第一个 RewriteRule。这也发生在 js 文件中(显然是因为还没有为它们设置规则)。

如果我使用相对路径或硬路径也没有区别......

分辨率

在继续努力使 apache 重定向工作后,我不得不为每个外部源位置添加一个特定的行(不知道为什么“不要恐慌”中的原始 RegEx 语句不起作用)。这是我的 .htaccess 文件现在的样子:

# these are for the external file requests
RewriteRule [a-z][a-z]/images/([a-zA-Z0-9_\.]+)$ /images/$1 [L]
RewriteRule [a-z][a-z]/styles/([a-zA-Z0-9_\.]+)$ /styles/$1 [L]

# these are for the main request for the bootstrap php file
RewriteBase /  
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ([a-z][a-z])/([a-zA-Z0-9]+) index.php?first=$1&second=$2 [L]

还要注意:如果您有任何未在此示例中创建的外部文件(例如 styles/non_existent.css),则上面的最后一个“RewriteRule”将执行并基本上运行 index.php 文件,从而导致您的站点出错.因此,请确保创建(或删除对)外部文件的引用——即使它们是空白的!!!

感谢您对“不要惊慌”的所有帮助!

【问题讨论】:

  • 看起来你已经修改了我提供的第一个重写规则,现在它也将匹配你的 CSS,这可能是一个问题。不清楚你为什么修改它,1234567890 不包括大写或小写字母,所以在正则表达式中不需要它们?回复:Browser: domain.com/ab/include/style.css - 这是什么意思?您是在地址栏中输入该值吗? $_SERVER['QUERY_STRING']: first=ab&second=include - 你如何看待 $_SERVER 对 CSS 文件的请求的值?
  • 0123456789 只是一个示例值。在现实生活中,值可以是我实现的 a-zA-Z0-9。这只是一个正则表达式匹配。它不匹配 '/' 字符,这意味着它不会匹配子目录,并且是第二条规则,使其成为最后一个要比较的规则。它也与'.'不匹配。字符意味着它不会匹配文件,因为它们将具有包含“.”的文件扩展名。您询问的“浏览器:”请求是浏览器请求的文件。
  • 要查看服务器正在请求哪些文件,index.php 文件只是将 $_SERVER['REQUEST_URI'] 和 $_SERVER['QUERY_STRING'] 值输出到文本文件。这样我就可以看到有什么请求进来了。除了原始请求之外的每个额外请求都是通过 HTML 请求的所有外部文件。
  • 很难从字里行间了解您正在尝试做什么,以及您实际在做什么,而且它并没有变得更容易:-) 听起来您现在已经修改了 CSS重定向我建议实际由index.php处理,这样你就可以看到$_SERVER变量?我不确定这样做的目的,但我建议暂时忘记$_SERVER。查看您的浏览器在开发工具中发出的请求。我的答案中的规则在一个干净的 Apache 2 容器中工作,并且与我从您的问题中理解的内容相匹配,尽管我完全理解不正确。

标签: php apache redirect


【解决方案1】:

据我了解,这些是您的要求:

  • 您希望将最初请求的 URL 保留在浏览器中,即不是外部的、对访问者可见的 301 类型重定向。换句话说,将浏览器中的 URL 透明地映射到文件系统上的其他内容。

  • 传入的请求包括2个可以用正则表达式匹配的段;

  • 您希望能够以 PHP 参数的形式访问请求的这 2 个目录元素;

Apache 内部重定向将执行此操作。 Apache 文档中mod_rewrite examples page 的第一个示例描述了这一点(尽管您可能不需要在那里使用[PT] 标志,which allows 进一步处理映射的URI)。我认为以下应该做你需要的:

RewriteEngine on
RewriteRule ([a-z][a-z])/([0-9]+) index.php?first=$1&last=$2 [L]

这将处理像domain.com/ab/1234567890 这样的传入请求,并将它透明地、不可见地映射到index.php?first=ab&last=1234567890。访问者看不到任何重定向,只有浏览器中的原始 URL。您仍然可以通过$_SERVER 访问外部请求和内部处理的不同元素:

...
[QUERY_STRING] => first=ab&last=1234567890
[REQUEST_URI] => /ab/1234567890
[SCRIPT_NAME] => /index.php
[PHP_SELF] => /index.php
...
[argv] => Array
    (
        [0] => first=ab&last=1234567890
    )

例如,您可以在代码中使用$_GET['first'] 来查找ab

更新

要回答 cmets 中添加的额外问题 - 要从 index.php 引用您的 CSS/JS,最简单和最有效的选择是使用绝对引用:

<link href="/css/some.css" rel="stylesheet">

如果您不能这样做,而是希望相对链接起作用,您可以尝试另一个内部重新映射。请注意,带有[R=301] 的外部重定向(就像您在 cmets 中显示的那样)会更慢,因为它确实是一个全新的请求和响应。

假设您有 include/file.css 之类的 CSS 文件,其中 include/ 目录与 index.php 位于同一目录中,那么 index.php 中的相对 CSS 引用如下:

<link href="include/some.css" rel="stylesheet">

将 - 使用上面的第一个重定向规则 - 实际上会生成对 ab/include/some.css 的请求。要将其重新映射到您的真实文件,可以使用以下内部重定向规则:

RewriteRule ^[a-z][a-z]/([a-z/]+.css)$ $1 [L]

请注意,您现在需要注意规则不会相互重叠或相互干扰,因此我在两者中都添加了[L],并且还在 CSS 正则表达式中添加了一些锚点。

【讨论】:

  • 所以看起来我在 PHP 中使用了错误的变量('QUERY_STRING' 而不是 'REQUEST_URI')——后者仍然显示原始请求。但是后续对外部 css 文件和 js 文件之类的文件请求仍然以“ab”(在上面的示例中)而不是根为前缀。我该如何解决?
  • 听起来您使用的是相对引用?所以使用绝对的,比如&lt;link ... href="/some.css"&gt;?
  • 我使用的是相对引用。有没有办法在apache中执行这个任务?我尝试使用“RewriteRule [az][az]/([a-zA-Z0-9]+\.[a-zA-Z0-9]+)$ $1 [R=301]”,但这并没有解决任何问题。
  • 所以我尝试使用 HTML 中的绝对链接以及额外的重定向(有和没有绝对链接),但该站点根本无法运行。外部 js 和 css 文件未加载。我将更新我的 OP 以反映更改...
  • 听起来你的配置中有其他东西在起作用。我提供的规则有效——我将它们设置在一个新的 Apache 2 Docker 容器中,并对其进行了广泛的测试。我建议将所有内容都注释掉并迭代测试。如果指向您的真实文件的绝对链接(与您的重定向规则不匹配)不起作用,则显然有问题或涉及其他问题,例如另一个 .htaccess 或重定向或 Apache 别名或 ....
【解决方案2】:

一旦页面更改,URL 将始终更改。避免这种情况的方法是使用 javascript 并在 div 中加载 url 内容或在 html 中使用 iframe 来显示目标页面。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-18
  • 2013-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多