2

做个前端,来点Nginx

 2 years ago
source link: http://www.androidchina.net/7477.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

做个前端,来点Nginx – Android开发中文站

你的位置:Android开发中文站 > 热点资讯 > 做个前端,来点Nginx

自从Nodejs火了,前端能做的事、要做的事越来越多了;同时对前端的要求也就越来越高,如果现在还只是停留在浏览器端写页面做交互,估计很难找到(更好的)工作了,Node中间层、Node微服务、网关这些可以和业务分离的地方以后可能都是前端的事了;Nodejs是把锋利的瑞士军刀,但你也不要想多了;合理的选型,各司其职,职尽其能,才能发挥各自最大的作用;毕竟一切从实际出发,实事求是,理论联系实际才是最佳的方法论;比如Nodejs可以做反向代理(http-proxy),可以很快的搭建静态资源站,但这些并不是Nodejs最擅长的,这些交给Nginx显然是个更好的选择,既可以把这些事做更好,还给Nodejs服务减压了!

一、快速拾起Nginx

Nginx是一个高性能的Web和反向代理服务器,稳定、强大、系统资源占用低,这些就不说了;

在nginx.conf这个配置文件里,一个server {}块可以对应一个站点的服务,每个server {}块里可以配置多个location {}块来对站点进行路由级别的控制,既可以通过proxy_pass target设置反向代理的server,也可以直接通过root dir来访问目录下的静态文件;server_name设置访问的域,多个用空格隔开,或者用通配符和正则;location后面可以是正则以及nginx提供的丰富的匹配符和变量;记住大括号前面的空格不能省,每行结束语句的分号不能省;

a. 比如用Nodejs启动了一个站点监听3000端口,用a.famanoder.cn来访问

server {
    listen 80;
    server_name a.famanoder.cn;

	location / {
        proxy_pass http://localhost:3000;
    }
}

b. 比如把所有的静态资源放到了dist目录,用cdn.famanoder.cn来访问

server {
    listen 80;
    server_name cdn.famanoder.cn;

	location / {
        index index.html;
        root D:\sources\dist;
    }
}

c. 用vue做的一个移动端的项目,用m.famanoder.cn来访问,所有数据接口由famanoder.cn提供;

server {
    listen 80;
    server_name m.famanoder.cn;

	location /api {
		# 代理api,以免跨域
        proxy_pass https://famanoder.cn;
    }
    location / {
        index index.html;
        root D:/vue/dist;
    }
}

以上只是最简单的站点和反向代理设置,通过匹配符和正则可以做更多的控制;

二、常用匹配符和变量

=   等于,严格匹配

!=  不等于

~   区分大小写匹配

!~  区分大小写不匹配

~*  不区分大小写匹配

!~* 不区分大小写不匹配

*   任意字符

-f和!-f 判断是否存在文件

-d和!-d 判断是否存在目录

-e和!-e 判断是否存在文件或目录

-x和!-x 判断文件是否可执行

对于location,匹配的优先级为:

(location =) > (location 完整路径) > (location ^~ 路径) > (location ~,~* 正则顺序) > (location 部分起始路径) > (/)

Nginx里有if指令,但是没有else指令和&&判断,但可以通过set变通的实现:

比如限制GET请求参数中的SQL关键词:

set $invalidQuery 1;
if( $request_method = GET ){
	set $invalidQuery '${invalidQuery}1';
} 
if( $query_string ~* "select|union|exec" ){
	set $invalidQuery '${invalidQuery}1';
} 
if( $invalidQuery = '111' ){
	return 403;
}

常用变量:

$args : 请求行中的参数,同$query_string。等于js中的location.search.slice(1)。

$content_type : 请求头中的Content-Type字段。

$document_root : 当前请求在root指令中指定的值。

$host : 请求主机头字段,否则为服务器名称。等于js中的location.host。

$http_user_agent : 客户端agent信息。等于js中的navigator.userAgent。

$http_cookie : 客户端cookie信息。等于js中的document.cookie。

$limit_rate : 这个变量可以限制连接速率。

$request_method : 客户端请求的动作,通常为GET或POST。

$remote_addr : 客户端的IP地址。

$remote_port : 客户端的端口。等于js中的location.port。

$http_referer :网页来源。等于js中的document.referer。

$remote_user : 已经经过Auth Basic Module验证的用户名。

$request_filename : 当前请求的文件路径,由root或alias指令与URI请求生成。

$scheme : HTTP方法(如http,https)。等于js中的location.protocol。

$server_protocol : 请求使用的协议,通常是HTTP/1.0或HTTP/1.1。

$server_addr : 服务器地址,在完成一次系统调用后可以确定这个值。

$server_name : 服务器名称。

$server_port : 请求到达服务器的端口号。

$request_uri : 包含请求参数的原始URI,不包含主机名,等于js中的location.pathname+location.search。

$uri : 不带请求参数的当前URI,$uri不包含主机名,等于js中的location.pathname。

$document_uri : 与$uri相同。

三、常见设置

1、worker_processes 4   # 开启多进程,一般为cpu核数,等于Nodejs中的require(‘os’).cpus().length

2、error_log  logs/error.log  info;   # log文件的地址和级别(debug, info, notice, warn, error, crit)

3、log_format 格式名称 具体格式   # 定义日志内容的格式可以包含$remote_addr $status $http_user_agent等参数

4、开启gzip

gzip  on;

gzip_proxied any;

gzip_min_length  1024;

gzip_buffers     4 8k;

gzip_types       text/css application/javascript application/atom+xml application/rss+xml text/plain image/svg+xml application/json text/javascript;

默认的配置文件中只有gzip on作用不大,需要自行配置后续gzip字段;给所有需要开启gzip的资源添加mimeType,图片不需要gzip(没有明显效果,体积还可能增大),白白损耗性能;

四、解决前端跨域问题

在前后端分离的时候,前后端搭建了两套环境,前端请求数据的时候会跨域,一般是用Nodejs做中转,比如使用http-proxy和request模块,或者在webpack的dev-server里配置proxy,浏览器兼容性比较理想的情况下还可以直接设置CORS;这样对于打包上线也不需要做太多改动;当然有时候还需要jsonp;

1. 设置CORS

server {
    listen 80;
    server_name cdn.famanoder.cn;

    location / {
    	add_header Access-Control-Allow-Origin *;  
        add_header Access-Control-Allow-Credentials true;  
        add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
        index index.html;
        root D:/sources/dist;
    }
}
# 如果不想设置星号的话,这个变通的做法貌似更灵活,还可以通过跨域反过来限制某些资源的是否可访问
if ($http_referer ~* 'famanoder.cn') {  
    add_header Access-Control-Allow-Origin *;  
    add_header Access-Control-Allow-Credentials true;  
    add_header Access-Control-Allow-Methods GET,POST,OPTIONS;  
}

2. 做api中转

server {
    listen 80;
    server_name m.famanoder.cn;

    location /api {
    	proxy_pass https://localhost:3000;
    }
}

五、从http切换到https

对于一般的散户来说,Letsencrypt是个不错的选择,可以免费为多个域名提供一套证书(散户福利!Nodejs多站点切换Htpps协议);可以新建一个站点专门为申请证书服务,以免以后重新申请时重启应用或再次搭建;对于切换到https,只需在80端口上直接对指定域名做301跳转到https对应地址,server块内做很小改动即可:

server {
    listen 80;
    server_name *.famanoder.com famanoder.com;

    location / {
    	# 迁移到https
        return 301 https://$host$request_uri;
    }

    location ~* 'acme-challenge' {
		# 2333端口留做以后申请证书用
        proxy_pass http://localhost:2333;
    }
}
server {
	# 监听443端口,开启ssl
    listen 443 ssl;
    server_name cdn.famanoder.cn;
    # 把申请到的证书加进来
    ssl_certificate      D:/crt.pem;
	ssl_certificate_key  D:/key.pem;

	location / {
        index index.html;
        root D:\sources\dist;
    }
}

六、Nginx真的超级强大,而且配置起来并不繁琐,常常简单的设置就可以达到非常强大的功能,比如做安全访问限制、负载均衡等;

如果你很喜欢一个东西,那么是否应该拿它来做更多有意义的事情!如果你很喜欢JS,那么是否应该拿它来做更多有意义的事情!那么好的,听说新版Nginx开始支持js语法了!如果你已在路上,就勇敢的向前吧!

转载请注明:Android开发中文站 » 做个前端,来点Nginx


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK