我正在运行 nginx + apache 配置。我对 nginx 非常非常陌生,我花了相当多的时间来学习它。
首先,我想进行基本的重写。根据我的理解,当 nginx 用作反向代理时 - apache 中的 .htaccess 应该仍然有效。遗憾的是 - 我的理解并不完全正确 - 有些部分有效,而其他部分似乎无效。
所以我尝试用 .htaccess 做了基本的重写
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?index.* /fp/ [P]
我发现在 .htaccess 中使用 [P] 标志而不是正常的重写会导致无法找到 /index.html 的错误(整个网站上没有任何 index.html,所以显然找不到它)。
我也尝试使用 [L] 标志,但它并没有像我期望的那样默默转发,而是进行了重定向,以便用户可以在地址栏中看到 /fp/——这不是我想要的结果。
因此 - 我将重定向移至 nginx 配置。这似乎运行正常。
我所做的 nginx 重定向非常简单,使用 if 语句
if ($uri = '/'){
rewrite / /fp/ break;
}
此重定向仅重定向至 /,而不重定向至 /index.php 或任何其他文件。
https://
接下来我有一个名为 /login.php 的文件。如果用户通过以下方式访问,我想将用户转发到http://
所以我尝试使用 Apache 方案检查,$_SERVER['REQUEST_SCHEME'];
问题是 - 它返回的http
是它https://
还是http://
login.php 位于 /
那么对于初学者来说,如何才能让 http 仅在 login.php 页面上重定向到 https。
我还应该注意,我尝试使用 .htaccess 从 http 重定向到 https,但由于服务器返回的是 http 而不是 https,因此导致了无限循环。
除此之外,为什么 apache .htaccess [P] 标志会导致搜索 index.html 以及为什么 silect 重定向会突然变得公开?
如果我需要展示我的配置 - 请告诉我哪些:)
更新以显示配置
nginx.conf
server {
proxy_pass_request_headers on;
index index.php;
listen 192.227.210.138:80;
server_name adsactlyhits.com www.adsactlyhits.com;
error_log /var/log/apache2/domains/adsactlyhits.com.error.log error;
location / {
if ($uri = '/'){
rewrite / /fp/ break;
}
proxy_pass http://192.227.210.138:8080;
location ~* ^.+\.(jpeg|jpg|png|gif|bmp|ico|svg|tif|tiff|css|js|ttf|otf|webp|woff|txt|csv|rtf|doc|docx|xls|xlsx|ppt|pptx|odf|odp|ods|odt|pdf|psd|ai|eot|eps|ps|zip|tar|tgz|gz|rar|bz2|7z|aac|m4a|mp3|mp4|ogg|wav|wma|3gp|avi|flv|m4v|mkv|mov|mpeg|mpg|wmv|exe|iso|dmg|swf)$ {
root /home/adsactly/web/adsactlyhits.com/public_html;
access_log /var/log/apache2/domains/adsactlyhits.com.log combined;
access_log /var/log/apache2/domains/adsactlyhits.com.bytes bytes;
expires max;
try_files $uri @fallback;
}
}
location /error/ {
alias /home/adsactly/web/adsactlyhits.com/document_errors/;
}
location @fallback {
proxy_pass http://192.227.210.138:8080;
}
location ~ /\.svn/ {return 404;}
location ~ /\.git/ {return 404;}
location ~ /\.hg/ {return 404;}
location ~ /\.bzr/ {return 404;}
include /home/adsactly/conf/web/nginx.adsactlyhits.com.conf*;
}
配置文件
server {
listen 192.227.210.138:443;
server_name adsactlyhits.com www.adsactlyhits.com;
ssl on;
ssl_certificate /home/adsactly/conf/web/ssl.adsactlyhits.com.pem;
ssl_certificate_key /home/adsactly/conf/web/ssl.adsactlyhits.com.key;
error_log /var/log/apache2/domains/adsactlyhits.com.error.log error;
location / {
if ($uri = '/'){
rewrite / /fp/ break;
}
proxy_pass http://192.227.210.138:8080;
proxy_cache cache;
proxy_cache_valid 15m;
proxy_cache_valid 404 1m;
proxy_no_cache $no_cache;
proxy_cache_bypass $no_cache;
proxy_cache_bypass $cookie_session $http_x_update;
location ~* ^.+\.(jpeg|jpg|png|gif|bmp|ico|svg|tif|tiff|css|js|ttf|otf|webp|woff|txt|csv|rtf|doc|docx|xls|xlsx|ppt|pptx|odf|odp|ods|odt|pdf|psd|ai|eot|eps|ps|zip|tar|tgz|gz|rar|bz2|7z|aac|m4a|mp3|mp4|ogg|wav|wma|3gp|avi|flv|m4v|mkv|mov|mpeg|mpg|wmv|exe|iso|dmg|swf)$ {
proxy_cache off;
root /home/adsactly/web/adsactlyhits.com/public_html;
access_log /var/log/apache2/domains/adsactlyhits.com.log combined;
access_log /var/log/apache2/domains/adsactlyhits.com.bytes bytes;
expires max;
try_files $uri @fallback;
}
}
location /error/ {
alias /home/adsactly/web/adsactlyhits.com/document_errors/;
}
location @fallback {
proxy_pass http://192.227.210.138:8080;
}
location ~ /\.ht {return 404;}
location ~ /\.svn/ {return 404;}
location ~ /\.git/ {return 404;}
location ~ /\.hg/ {return 404;}
location ~ /\.bzr/ {return 404;}
include /home/adsactly/conf/web/nginx.adsactlyhits.com.conf*;
}
<?php echo $_SERVER['REQUEST_SCHEME']; ?>
返回:http
<?php echo $_SERVER['REQUEST_SCHEME']; ?>
返回:http
答案1
那么首先,我如何才能让 http 仅在 login.php 页面上重定向到 https
关键是 http 和 https 的服务器块不同。如果您从单个服务器块提供服务,那么您的控制会受到更多限制。类似这样的方法应该可行。
server {
server_name example.com;
listen 80;
location = login.php {
return 302 https://example.com/login.php;
}
}
server {
server_name example.com;
listen 443 ssl;
# define any locations required
}
从更大角度来看,您应该通过 https 为整个网站提供服务,以避免这些问题,除非有非常好的理由必须使用 http。您的应用程序可能必须意识到网站在 http 和 https 之间被分段,以支持此设置。
此外,通常不需要将 Nginx 和 Apache 一起使用。Nginx 可以完成 Apache 可以完成的大部分工作,同时使用两者会增加复杂性。
当你需要在 Nginx 中使用“if”时,你应该考虑Nginx“if is evil”文章。我确实使用 if,但仅用于设置控制缓存指令的变量,而不是用于任何关键或流程相关的变量。您应该尽可能避免使用“if”。
更新
本文向您展示如何将协议等标头传递到下一层,以便它知道原始协议。您最好完全摆脱 Apache,让 Nginx 使用 php-fpm 调用 PHP。
location / {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://example.com/new/prefix;
}
删除 If 重定向
相反
location / {
if ($uri = '/'){
rewrite / /fp/ break;
}
// etc
}
您可以尝试类似这样的操作。等号运算符是精确匹配运算符。这将提供更好的性能(略微)和更可靠的操作。
location = / {
rewrite / /fp/ break;
}
location / {
// etc
}
我自己没有使用过重写,所以我不知道这是否是完成你尝试做的事情的最佳方法。