nginx
内容为 nginx基本使用,nginx代理跨域理解
Nginx是一个轻量级、高性能、稳定性高、并发性好的HTTP和反向代理服务器。
(1)常用操作 1 2 3 4 5 6 7 8
| #启动 nginx #关闭 nginx -s stop #修改了配置,重新加载 nginx -s reload #检查配置文件格式 nginx -t
|
配置文件地址:mac=>/usr/local/etc/nginx/nginx.conf ,
docker=>/etc/nginx
配置文件结构说明
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| user nginx; worker_processes 1;
error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid;
events { worker_connections 1024; }
http { include /etc/nginx/mime.types; default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on; #tcp_nopush on;
keepalive_timeout 65;
server { listen 80; listen [::]:80; server_name localhost;
#charset koi8-r; #access_log /var/log/nginx/host.access.log main; #接收到请求,去/usr/share/nginx/html目录下找静态资源,index.html或index.htm location / { root /usr/share/nginx/html; index index.html index.htm; #proxy_pass http://localhost:8081/; }
#error_page 404 /404.html;
error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; }
} #gzip on; #引入conf.d文件夹下以.conf结尾的配置文件 include /etc/nginx/conf.d/*.conf; }
|
(2)代理
数据请求:浏览器=>代理服务器=>目标服务器
数据返回:目标服务器=>代理服务器=>浏览器
例子:科学上网。
从服务器的角度,没有办法分辨请求来自代理还是浏览器,代理的本质是隐藏了客户端。
(3)反向代理
数据请求:浏览器=>反向代理服务器=>目标服务器
数据返回:目标服务器=>反向代理服务器=>浏览器
流程和代理差不多,但是代理在浏览器端配置,而反向代理靠近服务器,在服务端配置。
从浏览器的角度,不知道请求最终被哪个服务器所处理,反向代理的本质是隐藏了服务端。
同源策略
(1)同源策略MDN
浏览器的一个安全策略,限制同源[协议、域名、端口都一致]的文档以及它们加载的脚本怎么与另一个源的资源交互。同源策略控制不同源之间的交互,这些交互通常分三类:
跨域写操作(Cross-origin
writes)一般是被允许的。例如链接(links),重定向以及表单提交。
跨域资源嵌入(Cross-origin
embedding)一般是被允许(后面会举例说明)。
跨域读操作(Cross-origin
reads)一般是不被允许的,但常可以通过内嵌资源来巧妙的进行读取访问
资源嵌入示例:
<script src="..."></script>
标签嵌入跨域脚本。语法错误信息只能被同源脚本中捕捉到。 <link
rel="stylesheet" href="...">
标签嵌入CSS。由于CSS的松散的语法规则,CSS的跨域需要一个设置正确的 HTTP
头部 Content-Type 。 通过 <img>
展示的图片。支持的图片格式包括PNG,JPEG,GIF,BMP,SVG,... 通过
<video> 和 <audio> 播放的多媒体资源。 通过 <object>、
<embed> 和 <applet> 嵌入的插件。 通过 @font-face
引入的字体。一些浏览器允许跨域字体( cross-origin
fonts),一些需要同源字体(same-origin fonts)。 通过<iframe>
载入的任何资源。站点可以使用 X-Frame-Options
消息头来阻止这种形式的跨域交互。
(2)跨域方案
jsonp |type|地址| |--|--| |前端|| |后端|http://localhost:8500|
前端:
1 2 3 4 5 6 7 8 9 10 11 12 13
| <script type="text/javascript"> var dataHandle = function(data) { alert( "jsonp调用服务端结果:" + data.result ); }; let url = 'http://127.0.0.1:8500?callback=dataHandle&name=jack'; var script = document.createElement('script'); script.setAttribute('src', url); document.getElementsByTagName('head')[0].appendChild(script); </script>
|
后端:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| const http = require("http"); const url = require("url"); const querystring = require("querystring"); var fs = require('fs')
const hostname = "127.0.0.1"; const port = 8500;
const server = http.createServer(); server.on("clientError", (err, socket) => { socket.end("HTTP/1.1 400 Bad Request\r\n\r\n"); });
server.on("request", (req, res) => { var arg = url.parse(req.url).query; var params = querystring.parse(arg);
const data = { jack:"i am jack", tom:"i am tom" } if (params.callback && params.callback == "dataHandle") { res.write(`dataHandle({"result":"${data[params.name]}"});`) res.end() } });
server.listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`); });
|
开启跨域资源共享(Cross-oringin resource sharing,CORS)MDN
前端 |
http://localhost:8081 |
后端 |
http://localhost:9000 |
在后端设置HTTP响应首部字段 Access-Control-Allow-Origin:
1
| response.setHeader('Access-Control-Allow-Origin', 'http://localhost:8081');
|
过程:浏览器通过8081直接请求9000服务端口
nginx反向代理
前端 |
http://localhost:8081 |
后端 |
http://localhost:8000 |
nginx |
代理8866端口,来自http://localhost:8866的请求转发到8000 |
1 2 3 4 5 6 7 8 9 10 11
| server { listen 8866; server_name 127.0.0.1; # 需要中转的请求 location / { proxy_pass http://127.0.0.1:8000; # 反向代理后端地址 index index.html index.htm; # 跨域配置,给浏览器设置响应头 add_header Access-Control-Allow-Origin http://localhost:8081; add_header Access-Control-Allow-Credentials true; } }
|
过程:浏览器从8081端口向nginx的8866端口请求数据,nginx反向代理8866端口,将对8866端口的请求转发给真实服务端接口8000.
解析:浏览器从8081端口向8866端口请求资源是跨域行为,须在nginx配置跨域如上。nginx到8000的代理请求不经过浏览器,不受浏览器的同源策略影响,可以访问。
总结:
nginx反向代理和CORS都是通过设置HTTP响应首部字段
Access-Control-Allow-Origin,开启跨域资源共享机制。不同点在于,nginx反向代理是nginx向浏览器开放,因而不需要服务器额外配置,而CORS是服务端向浏览器开放,需在服务端配置。