首页 > 解决方案 > 为什么添加 htaccess 规则后,特定页面中的 XHR 调用不起作用?

问题描述

我是 htaccess 的新手,对正则表达式真的很不好,所以这里什么都没有......

我正在构建一个非常简单和基本的 Web 应用程序。我有 5 页,处理应用程序中的所有内容。

home 只处理主页;login 只处理登录和帐户创建;内容处理站点中的所有其他页面;admin 只处理登录后面的管理部分;错误处理错误 - 显然

为了实现这一点,我不得不制定一些古怪的 htaccess 规则。登录表单是通过 ajax 提交的,所以这是第一个障碍。

我已经登录成功重定向到管理门户,并且管理门户将显示,但注销将不起作用,并且管理门户中的任何 ajax 功能都将不起作用。

到目前为止,这是我的 htaccess:

#I have no idea what this line does
Options -Indexes

# Turn on rewritting
RewriteEngine On

# This will get the admin portal to load it needs to go through the admin controller 
# not content, but nothing inside admin works
# /admin - works! 
# /admin/save, /admin/logout, /admin/getPage all fail and are submitted via ajax
RewriteCond %{REQUEST_URI} ^/(.*)/admin$
RewriteRule ^(.*)$ index.php?url=admin/default/ [L,NC,QSA]

# this let's the login form submission via ajax work successfully, otherwise it gets 
# processed by the last rule as a content page - it needs to go through the login 
# controller, not content.
RewriteCond %{REQUEST_URI} ^/(.*)/login/login$
RewriteRule ^(.*)$ index.php?url=login/login/ [L,NC,QSA]

# this handles all the other pages in the site successfully
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=content/default/$1 [L,NC,QSA]

我整天都在网上搜索这个问题的答案,我所拥有的可能是完全错误的,如果是这样,请告诉我,并告诉我为什么以及如何解决它(我想最后两个是可选的)。一旦我得到这个工作,我的应用程序就准备好了。所有帮助将不胜感激。

标签: php.htaccess

解决方案


使用查询字符串变量(如您的 )的更好替代方法url如下:

  • 通过index.php解析每个请求
  • 从全局变量的值中读取URI路径,并从. 将它们与其他全局变量($_POST、$_GET 等)的值一起保存到一个对象中(例如,一个名为 的类的实例)。REQUEST_URI$_SERVERREQUEST_METHODRequestRequest
  • 获取一个像FastRoute(我个人的选择)这样的路由器并建立你的路由列表 - 请阅读文档。每个路由都被定义为一个对象,它具有HTTP 方法模式处理程序(例如控制器方法,例如操作)作为属性。
  • 将请求组件(HTTP 方法和对象的URI 路径)与路由列表Request中每个路由对象的组件(HTTP 方法模式属性)进行比较。
  • 如果找到匹配项,例如,如果请求组件与路由的组件相同,则调用相应的路由处理程序,例如控制器操作。将对象作为参数传递Request,以便能够读取 POST、GET 等值。

现在关于配置(对于 Apache 2.2):

首先不要忘记拒绝对所有文件夹的访问!

<Directory />
    Options None
    AllowOverride None
    Order deny,allow
    Deny from all
</Directory>

然后虚拟主机配置看起来像这样 - 其中demoproj指的是 MVC 项目:

httpd-vhosts.conf

NameVirtualHost *:80

<VirtualHost *:80>
    ServerName localhost
    DocumentRoot "/path-to/htdocs"
</VirtualHost>

<VirtualHost *:80>
    ServerName local.demoproj
    DocumentRoot "/path-to/demoproj/public"
    Include "/path-to/httpd-vhosts-demoproj.conf"
</VirtualHost>

httpd-vhosts-demoproj.conf

<Directory "/path-to/demoproj/public">
    Allow from all

    # When off then RewriteRule directive is forbidden!
    # ---------------------------------------------------------------------------------------------
    # https://stackoverflow.com/questions/12120035/what-is-options-followsymlinks/26732503#26732503
    # https://stackoverflow.com/questions/12120035/what-is-options-followsymlinks/12129326#12129326
    # ---------------------------------------------------------------------------------------------
    Options FollowSymLinks

    # Activate rewriting engine.
    RewriteEngine On

    # Allow pin-pointing to index.php using RewriteRule.
    RewriteBase /

    # Rewrite url only if no physical folder name is given in url.
    RewriteCond %{REQUEST_FILENAME} !-d

    # Rewrite url only if no physical file name is given in url.
    RewriteCond %{REQUEST_FILENAME} !-f

    # Parse the request through index.php.
    # -----------------------------------------------------------------------------------------------------
    # https://httpd.apache.org/docs/current/rewrite/flags.html "RewriteRule Flags"
    # https://stackoverflow.com/questions/45997912/exposed-folders-in-mvc-application/45998123#45998123
    # https://stackoverflow.com/questions/2102128/mod-rewrite-what-does-this-rewriterule-do/2102189#2102189
    # -----------------------------------------------------------------------------------------------------
    RewriteRule ^(.*)$ index.php [QSA,L]
</Directory>

推荐阅读