如何结合index.php的RewriteRule和查询重写并避免服务器错误404?

如何结合index.php的RewriteRule和查询重写并避免服务器错误404?

两种 RewriteRule 都可以正常工作,除非一起使用。

1.删​​除除查询之外的所有查询?callback=.*

# /api?callback=foo       has no rewrite
# /whatever?whatever=foo  has 301 redirect  /whatever
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^?#\ ]*)\?[^\ ]*\ HTTP/ [NC]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} !/api(/.*)?\?callback=.*
RewriteRule .*$ %{REQUEST_URI}? [R=301,L]

2.重写索引.php查询apiurl=$1

# /api           returns data  index.php?api&url=
# /api/whatever  returns data  index.php?api&url=whatever
RewriteRule ^api(?:/([^/]*))?$ index.php?api&url=$1 [QSA,L]
RewriteRule ^([^.]*)$ index.php?url=$1 [QSA,L]

有没有任何有效的组合可以将此 RewriteRule 保持其功能?

此组合将返回服务器错误 404/api/?回调=foo

# Remove all queries except query "callback"
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^?#\ ]*)\?[^\ ]*\ HTTP/ [NC]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} !/api(/.*)?\?callback=.*
RewriteRule .*$ %{REQUEST_URI}? [R=301,L]

# Rewrite index.php queries
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} !/api(/.*)?\?callback=.*
# Server Error 404 on /api/?callback=foo and /api/whatever?callback=foo
RewriteRule ^api(?:/([^/]*))?$ index.php?api&url=$1 [QSA,L]
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} !/api(/.*)?\?callback=.*
RewriteRule ^([^.]*)$ index.php?url=$1 [QSA,L]

答案1

我想我必须把它说清楚,在有 3 条评论要求你!从你的条件中删除之后:

# Rewrite index.php queries
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} !/api(/.*)?\?callback=.*
# Server Error 404 on /api/?callback=foo and /api/whatever?callback=foo
RewriteRule ^api(?:/([^/]*))?$ index.php?api&url=$1 [QSA,L]

这是您显然试图处理/api请求的规则,这就是正在发生的事情:

  1. 您请求/api?callback=foo
  2. 对照条件检查RewriteCond %{REQUEST_URI}?%{QUERY_STRING} !/api(/.*)?\?callback=.*
  3. 不匹配,因为/api?callback=foo不匹配!/api(/.*)?\?callback=.*!“URI 不能是 /api”
  4. 规则结束,由于条件不满足什么也没有发生

另一个例子

  1. 您请求/blah/
  2. 对照条件检查RewriteCond %{REQUEST_URI}?%{QUERY_STRING} !/api(/.*)?\?callback=.*
  3. 条件匹配,因为/blah不是/api?callback=
  4. 尝试应用规则RewriteRule ^api(?:/([^/]*))?$ index.php?api&url=$1 [QSA,L]
  5. 规则失败,因为正则表达式说:URI 必须以 /api 开头,由于 URI 是/blah,规则不被应用,什么也不会发生。

因此,正如您所看到的,无论如何,您的规则永远不会执行任何操作。您需要更改条件,使其不会否定/api,因为你想要 /api,这是规则的重点. 只需匹配查询字符串:

RewriteCond %{QUERY_STRING} callback=
RewriteRule ^api(?:/([^/]*))?$ index.php?api&url=$1 [QSA,L]

只需删除就足够了,但它是多余的,因为无论如何你都在规则中!进行匹配:/api

# This works too
# Look! no more ! here -------------------v
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} /api(/.*)?\?callback=.*
RewriteRule ^api(?:/([^/]*))?$ index.php?api&url=$1 [QSA,L]

答案2

启用RewriteRule索引.php,需要添加查询重写例外情况。

此规则运行良好并修复了此问题:

# Remove question mark and parameters
RewriteCond %{QUERY_STRING} .+
# Query rewrite exceptions
RewriteCond %{REQUEST_FILENAME} !index.php
RewriteCond %{REQUEST_URI}?%{QUERY_STRING} !/api(/.*)?\?callback=.*
RewriteRule .*$ %{REQUEST_URI}? [R=301,L]

# index.php query rewrite
RewriteRule ^api(?:/([^/]*))?$ index.php?api&url=$1 [QSA,L]
RewriteRule ^([^.]*)$ index.php?url=$1 [QSA,L]

相关内容