Nginx区分PC版本和移动版本得配置

133 阅读1分钟

起因

运维老哥太忙了,没空配置,所以作为一个小前端只能自己上手配置一下啦 = =

需求

同一个域名可以根据环境自动区分读取PC还是mobile版得目录

配置如下:

  server {
    ...
    ...
    
    // 设置一个变量,默认是指向PC项目地址
    set $root_dir /data/wwwroot/.../XXPc;

    // 如果是移动版环境则改为指向移动版地址
    if ($http_user_agent ~* '(Android|webOS|iPhone|iPod|BlackBerry)') {
      set $root_dir /data/wwwroot/.../XXMoblie; 
    }
    
    
    location / {
      root $root_dir; 👈使用设置得变量
      index index.html index.htm;
      try_files $uri $uri/ /index.html?$query_string; 
    }
   
  }

新需求

omg,有个别页面只在移动版有如果pc打开则会404,需要特别指定一些页面用PC打开还要跳转到移动版 根据上面得经验我随手加了一条配置规则

  if ($request_uri ~ 'feedback') {
       set $root_dir /data/wwwroot/.../XXMoblie;
  }

满怀信心得F5刷新,白屏!!

F12看一下控制台然后逐条分析,首先

Dingtalk_20230720155853.jpg 页面肯定是已经被指向了移动版,同时jscss也都请求了,那么白屏得问题只能是出在js请求得结果了,果然查看一下js请求

Dingtalk_20230720160128.jpg 发现请求得结果居然是pc版本得h5页面,接着查看请求url就能分析出问题所在

Dingtalk_20230720160354.jpg

我们得匹配规则是

 if ($request_uri ~ 'feedback') {
      set $root_dir /data/wwwroot/.../XXMoblie;
 }
 
 匹配得是 feedback,而我们得js地址则是 /assets/xxxxx.js 这样自然是匹配不上会去请求pc得目录 
 

http_referer 登场

既然我们已经知道了问题得原因,自然不能再使用request_uri来匹配,这个时候就应该用http_referer这个关键字来匹配我们得js

HTTP参照位址referer,或HTTP referer)是HTTP表头的一个栏位,用来表示从哪儿连结到目前的网页,采用的格式是URL。换句话说,藉著HTTP参照位址,目前的网页可以检查访客从哪里而来,这也常被用来对付伪造的跨网站请求。而dereferer则是将HTTP参照位址资讯剥离,所以网站将无法识别访客从何而来。

以上信息来源维基百科

我们得jshtml发起得请求,所以referer自然是我们得页面地址,我们新增一条规则来匹配

  if ($http_referer ~ 'feedback') {
       set $root_dir /data/wwwroot/.../XXMoblie;
  }

现在完整的配置文件应该如下:

  server {
    ...
    ...
    
    // 设置一个变量,默认是指向PC项目地址
    set $root_dir /data/wwwroot/.../XXPc;

    // 如果是移动版环境则改为指向移动版地址
    if ($http_user_agent ~* '(Android|webOS|iPhone|iPod|BlackBerry)') {
      set $root_dir /data/wwwroot/.../XXMoblie; 
    }
    
    if ($request_uri ~ 'feedback') {
       set $root_dir /data/wwwroot/.../XXMoblie;
    }
    
    if ($http_referer ~ 'feedback') {
       set $root_dir /data/wwwroot/.../XXMoblie;
    }
    
    location / {
      root $root_dir; 👈使用设置得变量
      index index.html index.htm;
      try_files $uri $uri/ /index.html?$query_string; 
    }
   
  }

F5刷新,页面成功打开并且指向了移动版,但是紧接着又又又又发现了一个问题,那就是如果在feedback页面有跳转的逻辑,则打开的页面会被指定为移动版,这是因为跳转的时候referer被指定为了feedback页面,这个时候就又回到了我们前端代码的阶段

const meta = document.createElement('meta');  
meta.content = 'never';  
meta.name = 'referrer';  
document.getElementsByTagName('head')[0].appendChild(meta);  
window.location.href = "/";

我们设置一下跳转的时候不带referer,问题解决~

结束语

有时候一个小需求里就包含了大量的技术要求,学习了学习了,总体来说熟悉了一下nginx配置,技多不压身嘛~