概述
日萌社
人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新)
nginx+keepalived:局域网内网和公网外网 搭建nginx HA 双机热备 高可用
nginx 把 POST请求数据 写入到 日志文件中
nginx 自动解压gzip压缩数据的两种方式:nginx自动解压、后台java程序解压
nginx安装、nginx反向代理/负载均衡、Lua、LuaJIT、openresty、lua-nginx-module、ngx_devel_kit 的安装
nginx 配置获取GET请求参数、POST请求参数、nginx配置开启跨域访问、nginx+keepalived配置主备切换/双机热备、nginx优化配置
准备
yum -y install gcc gcc-c++ lua-devel pcre pcre-devel zlib zlib-devel
禁用 防火墙(重启生效)
查看防火墙状态 systemctl status firewalld
查看开机是否启动防火墙服务 systemctl is-enabled firewalld
关闭防火墙 systemctl stop firewalld
禁用防火墙 systemctl disable firewalld
禁用 SELINUX
1.临时关闭SELINUX
setenforce 0 ##设置SELinux 成为permissive模式
getenforce ##可以用这个命令检查是否为Permissive 或者为 Disabled
2.永久关闭SELINUX
修改配置文件 vim /etc/selinux/config(重启生效)
将 SELINUX=enforcing 改为 SELINUX=disabled
3.查看SELINUX状态 sestatus
getenforce ##可以用这个命令检查是否为Permissive 或者为 Disabled
reboot 重启机器后 执行 sestatus 显示 SELinux status: disabled
----------------LuaJIT ---------------------------
cd /home/gzp/soft
tar -zxvf LuaJIT-2.0.5.tar.gz
cd /home/gzp/soft/LuaJIT
make PREFIX=/data/luajit
make install PREFIX=/data/luajit
/etc/profile环境变量配置
方式一:vim /etc/profile
export LUAJIT_LIB=/data/luajit/lib
export LUAJIT_INC=/data/luajit/include/luajit-2.0
source /etc/profile
方式一:用户目录下的 .bash_profile 或 .bashrc 或 .profile
vim .bash_profile 或 vim .bashrc 或 vim .profile
export LUAJIT_LIB=/home/gzp/softs/luajit/lib
export LUAJIT_INC=/home/gzp/softs/luajit/include/luajit-2.0
source .bash_profile 或 source .bashrc
-------------nginx、ngx_devel_kit、lua-nginx-module 必须安装------------------------------
yum -y install gcc gcc-c++ lua-devel pcre pcre-devel zlib zlib-devel
需要同时编译安装 nginx-1.17.0.tar.gz、ngx_devel_kit v0.3.1rc1、lua-nginx-module v0.10.14
cd /home/gzp/soft
tar -xzvf nginx-1.17.0.tar.gz
tar -xzvf lua-nginx-module-0.10.14.tar.gz
tar -xzvf ngx_devel_kit-0.3.1rc1.tar.gz
cd /home/gzp/soft/nginx
./configure --prefix=/data/nginx --add-module=/home/gzp/soft/lua-nginx-module --add-module=/home/gzp/soft/ngx_devel_kit
make
make install
修改 vim /data/nginx/html/index.html 的页面内容 用于识别浏览器切换到哪台机器上的 nginx
如果启动nginx的不是root用户的话,需要修改 vim /data/nginx/conf/nginx.conf 中的端口号不能为80,否则报错
nginx 启动 和 加载指定nginx.conf配置文件的方式启动
cd /data/nginx/sbin 执行./nginx 或 ./nginx -c /data/nginx/conf/nginx.conf
/data/nginx/sbin/nginx
/data/nginx/sbin/nginx -c /data/nginx/conf/nginx.conf
/data/nginx/sbin/nginx -s stop
/data/nginx/sbin/nginx -s reload
kill -HUP pid
pid 是进程标识。如果想要更改配置而不需停止并重新启动服务,请使用该命令。
在对配置文件作必要的更改后,发出该命令以动态更新服务配置。
ps aux|grep nginx 会查询出nginx: master process 和 nginx: worker process 两种不同的进程
因此kill -HUP pid 中的进程号应该是nginx: master process的进程号
默认日志存放路径:/data/nginx/logs
ps aux|grep nginx
netstat -an | grep 80
报错:访问nginx的IP:80端口的页面时,出现403 Forbidden
解决:
将nginx.config的user改为和启动用户一致
vim /gzp/softs/nginx/conf/nginx.conf
将 #user nobody 改为 user gzp 或者 user root
启动时报错:./nginx: error while loading shared libraries: libluajit-5.1.so.2: cannot open shared object file: No such file or directory
解决:ln -s /data/luajit/lib/libluajit-5.1.so.2 /lib64/libluajit-5.1.so.2
nginx 配置获取GET请求参数、POST请求参数、nginx配置开启跨域访问
--------------------- nginx.conf 配置 ------------------------
user root;
worker_processes 8;
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
error_log /data/nginx/logs/error.log;
pid /data/nginx/logs/nginx.pid;
worker_rlimit_nofile 32768;
events
{
worker_connections 8192;
}
http
{
include 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 /data/nginx/logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
#需要记录的有哪些信息:time_local本地时间、msec时间戳、remote_addr访问IP、request_body请求参数、arg_username/arg_passwd(arg_GET请求的URL参数名)
#log_format nginx_log:nginx_log实际是自定义的日志格式名,代表了后面一连串的记录信息
log_format nginx_log '[$time_local] - $msec - $remote_addr - $request_body - $arg_username - $arg_passwd';
server
{
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
open_log_file_cache max=8;
client_max_body_size 8m;
client_body_buffer_size 8m;
client_body_in_single_buffer on;
location /
{
root html;
index index.html index.htm;
}
location /xxx
{
#添加可以跨域访问的请求头信息
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET,POST,PUT,DELETE,PATCH,OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
if ($request_method = 'OPTIONS')
{
return 204;
}
#开启可以记录请求参数
lua_need_request_body on;
#开启把请求参数记录本地
content_by_lua 'local body = ngx.var.request_body';
#nginx_log自定义的日志格式名代表了一连串的记录信息要存储到本地文件路径/data/nginx/logs/nginx.log中
access_log /data/nginx/logs/nginx.log nginx_log;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html
{
root html;
}
}
}
---------------------测试 nginx ------------------------
#GET请求参数、POST请求参数都会保存到给文件下
tail -F /data/nginx/logs/nginx.log
(get请求+URL参数)curl 'http://cdh02:80/xx?username=clannad&passwd=air'
curl -X GET 'http://cdh02:80/xx?username=clannad&passwd=air' # -X GET 可省略
(post请求+URL参数+post参数)curl 'http://cdh02:80/xx?username=clannad&passwd=air' -d 'username=qujun&passwd=xixi'
(post请求+post参数)curl -d "username=qujun&passwd=xixi" http://cdh02:80/xx
(post请求+post参数)curl -X POST --data "name=kk&name2=gg" http://cdh02:80/xx
(get请求:成功返回跨域头)
curl -I -X GET 'http://cdh02:80/xx?username=clannad&passwd=air' # -X GET 可省略
HTTP/1.1 200 OK
Server: nginx/1.17.0
Date: Thu, 08 Aug 2019 05:47:14 GMT
Content-Type: application/octet-stream
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET,POST,PUT,DELETE,PATCH,OPTIONS
Access-Control-Allow-Headers: DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization
(OPTIONS预检请求成功返回跨域头)
curl -I -X OPTIONS 'http://cdh02:80/xx?username=clannad&passwd=air'
HTTP/1.1 204 No Content
Server: nginx/1.17.0
Date: Thu, 08 Aug 2019 05:51:48 GMT
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET,POST,PUT,DELETE,PATCH,OPTIONS
Access-Control-Allow-Headers: DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization
nginx+keepalived 配置 主备切换/双机热备
-------------------------------keepalived 安装---------------------------------------
yum -y install openssl-devel
cd /home/gzp/soft
tar -zxvf keepalived-2.0.16.tar.gz
cd /home/gzp/soft/keepalived
./configure --prefix=/data/keepalived
make
make install
建立软链接
ln -s /data/keepalived/sbin/keepalived /sbin/
ln -s /data/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/
ln -s /data/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
keepalived 启动 和 加载指定nginx.conf配置文件的方式启动
keepalived -D -f /data/keepalived/etc/keepalived/keepalived.conf
/data/keepalived/etc/sysconfig/keepalived -D -f /data/keepalived/etc/keepalived/keepalived.conf
keepalived 关闭(yum install psmisc)
killall keepalived
netstat -an | grep 112 默认端口
ps aux|grep keepalived
service keepalived restart 或 /bin/systemctl restart keepalived.service
service keepalived status 或 /bin/systemctl status keepalived.service
service keepalived stop 或 /bin/systemctl stop keepalived.service
service keepalived start 或 /bin/systemctl start keepalived.service
默认日志存放在系统日志:cat /var/log/messages
日志中错误信息1:
Unsafe permissions found for script
script_user #脚本执行用户,该参数是我们根据官方说明手动添加的,默认没有,如果不添加,会报错 WARNING - default user 'keepalived_script' for script execution does not exist - please create.
enable_script_security #设置脚本的可运行性,该参数是我们根据官方说明手动添加的,默认没有,如果不添加,会报错 WARNING - default user 'keepalived_script' for script execution does not exist - please create.
解决:
global_defs
{
script_user gzp #用户名
enable_script_security
}
---------------------------keepalived.conf配置----------------------------------------------
应该要符合以下3条才能成功的
1.广播地址要 一样的
2.外网IP 之间可以互相ping通
3.vip虚拟IP 要用通过路由创建出来的外网IP(并且能访问外网),不能用外网网卡唯一IP
检测脚本
vim /data/keepalived/chk_nginx_pid.sh
cd /data/keepalived
chmod 777 chk_nginx_pid.sh
#!/bin/bash
A=`ps -C nginx --no-header |wc -l`
if [ $A -eq 0 ]
then
echo 'nginx server is died'
sudo killall keepalived
fi
----------cdh01(master)----------------
vim /data/keepalived/etc/keepalived/keepalived.conf
global_defs
{
script_user root #用户名
enable_script_security
}
vrrp_script check_nginx
{
script "/data/keepalived/chk_nginx_pid.sh" #通过脚本监测
interval 3 #脚本执行间隔,每3s检测一次
}
vrrp_instance http
{
state MASTER #指定keepalived的角色,MASTER表示此主机是主服务器,BACKUP表示此主机是备用服务器
interface eno1 #指定HA监测网络的网卡
mcast_src_ip 外网IP #发送多播数据包时的源IP地址
virtual_router_id 60 #虚拟路由标识,MASTER和BACKUP必须是一致的
priority 110 #定义优先级,数字越大,优先级越高,MASTER的优先级必须大于BACKUP的优先级
advert_int 1 #设定MASTER与BACKUP负载均衡器之间同步检查的时间间隔,单位是秒
authentication
{
auth_type PASS #设置vrrp验证类型,主要有PASS和AH两种
auth_pass 1234 #设置vrrp验证密码,MASTER与BACKUP必须使用相同的密码才能正常通信
}
virtual_ipaddress #VRRP HA 虚拟地址 如果有多个VIP,继续换行填写
{
路由IP
}
track_script #执行监控的服务
{
check_nginx #引用vrrp_script配置项。定期运行执行监控,并最终引发主备切换
}
}
----------cdh02(backup)----------------
vim /data/keepalived/etc/keepalived/keepalived.conf
global_defs
{
script_user root #用户名
enable_script_security
}
vrrp_script check_nginx {
script "/data/keepalived/chk_nginx_pid.sh"
interval 3
}
vrrp_instance http {
state BACKUP
interface eno1
mcast_src_ip 外网IP
virtual_router_id 60
priority 105
advert_int 1
authentication {
auth_type PASS
auth_pass 1234
}
virtual_ipaddress {
路由IP
}
track_script {
check_nginx
}
}
keepalived 启动 和 加载指定nginx.conf配置文件的方式启动
keepalived -D -f /data/keepalived/etc/keepalived/keepalived.conf
/data/keepalived/etc/sysconfig/keepalived -D -f /data/keepalived/etc/keepalived/keepalived.conf
keepalived 关闭(yum install psmisc)
killall keepalived
netstat -an | grep 112 默认端口
ps aux|grep keepalived
默认日志存放在系统日志:cat /var/log/messages
ip addr
cdh01(master)
eno1:存在 vip地址
cdh02(backup)
eno1:不存在 vip地址
测试:停掉cdh01的nginx,同时keepalived自动执行脚本chk_nginx_pid.sh,keepalived也会自动停止
/data/nginx/sbin/nginx -s stop
ps aux|grep nginx
cdh01(master)
eno1:不存在 vip地址
cdh02(backup)
eno1:存在 vip地址
测试:重新启动cdh01的nginx、keepalived,必须先启动nginx 再启动keepalived,因为一启动keepalived,cdh02的vip就会重新漂移回到cdh01上
keepalived -D -f /data/keepalived/etc/keepalived/keepalived.conf
/data/nginx/sbin/nginx -c /data/nginx/conf/nginx.conf
ps aux|grep keepalived
ps aux|grep nginx
其他参考写法:nginx 配置获取GET请求参数、POST请求参数
log_format nginx_log '[$time_local] - $msec - $remote_addr - $request_body';
log_format nginx_log '[$time_local] - $msec - $remote_addr - $request_body - $args - $query_string - $arg_username - $arg_passwd';
location /xx
{
lua_need_request_body on;
content_by_lua '
local body = ngx.var.request_body;
ngx.say(body);
';
content_by_lua_block
{
local body = ngx.var.request_body;
local username = ngx.var.arg_username;
local passwd = ngx.var.arg_passwd;
ngx.say(body);
ngx.say(username);
ngx.say(passwd);
}
content_by_lua_block
{
local arg = ngx.req.get_uri_args()
for k,v in pairs(arg) do
ngx.say("[GET ] key:", k, " v:", v)
end
ngx.req.read_body() -- 解析 body 参数之前一定要先读取 body
local arg = ngx.req.get_post_args()
for k,v in pairs(arg) do
ngx.say("[POST] key:", k, " v:", v)
end
}
access_log /home/data/nginx/logs/nginx.log nginx_log;
}
access_by_lua与content_by_lua的区别
1.二者是nginx对于请求的不同处理阶段。
2.access_by_lua在请求访问阶段处理,用于访问控制,适用于http、server、location、location if。
3.content_by_lua是内容处理器,接受请求并输出响应,适用于location、location if。
获取url参数
在 ngx_lua 中访问 Nginx 内置变量 ngx.var.arg_PARAMETER 即可获得GET参数PARAMETER的内容。
在 nginx配置中,通过$arg_PARAMETER 即可获得GET参数PARAMETER的内容。
获取请求头
在 ngx_lua 中访问 Nginx 内置变量 ngx.var.http_HEADER 即可获得请求头HEADER的内容。
在 nginx配置中,通过$http_HEADER 即可获得请求头HEADER的内容。
参数的变化:可以使用“arg_参数名”去匹配到具体参数所带的值
最后的“?”可以阻止请求中原来的参数再带过来放到重写后的url里
其他有用的nginx全局变量
arg_PARAMETER #这个变量包含GET请求中,如果有变量PARAMETER时的值。
args #这个变量等于请求行中(GET请求)的参数,如:foo=123&bar=blahblah;
binary_remote_addr #二进制的客户地址。
body_bytes_sent #响应时送出的body字节数数量。即使连接中断,这个数据也是精确的。
content_length #请求头中的Content-length字段。
content_type #请求头中的Content-Type字段。
cookie_COOKIE #cookie COOKIE变量的值
document_root #当前请求在root指令中指定的值。
document_uri #与uri相同。
host #请求主机头字段,否则为服务器名称。
hostname #Set to themachine’s hostname as returned by gethostname
http_HEADER
is_args #表示请求中的URL是否带参数,如果带参数,$is_args值为"?"。如果不带参数,则是空字符串
http_user_agent #客户端agent信息
http_cookie #客户端cookie信息
limit_rate #这个变量可以限制连接速率。
query_string #与args相同。
request_body_file #客户端请求主体信息的临时文件名。
request_method #客户端请求的动作,通常为GET或POST。
remote_addr #客户端的IP地址。
remote_port #客户端的端口。
remote_user #已经经过Auth Basic Module验证的用户名。
request_completion #如果请求结束,设置为OK. 当请求未结束或如果该请求不是请求链串的最后一个时,为空(Empty)。
request_method #GET或POST
request_filename #当前请求的文件路径,由root或alias指令与URI请求生成。
request_uri #包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。不能修改。
scheme #HTTP方法(如http,https)。
server_protocol #请求使用的协议,通常是HTTP/1.0或HTTP/1.1。
server_addr #服务器地址,在完成一次系统调用后可以确定这个值。
server_name #服务器名称。
server_port #请求到达服务器的端口号。
ngx.var.arg_xx与ngx.req.get_uri_args["xx"] 两者都是为了获取请求uri中的参数
例如 http://pureage.info?strider=1 为了获取输入参数strider,以下两种方法都可以:
local strider = ngx.var.arg_strider
local strider = ngx.req.get_uri_args["strider"]
差别在于,当请求uri中有多个同名参数时,ngx.var.arg_xx的做法是取第一个出现的值
ngx.req_get_uri_args["xx"]的做法是返回一个table,该table里存放了该参数的所有值
例如,当请求uri为:http://pureage.info?strider=1&strider=2&strider=3&strider=4时,
ngx.var.arg_strider的值为"1",而ngx.req.get_uri_args["strider"]的值为table ["1", "2", "3", "4"]。
因此,ngx.req.get_uri_args属于ngx.var.arg_的增强。
curl 命令
-X/--request <command> 参数
指定什么命令,如 GET、POST。
例:
curl -X GET http://localhost:8080/search?data=123 # -X GET是可选的
curl -X POST -d "data=123&key=456" http://localhost:8080/search
# JSON数据以 请求体(body) 方请求
curl -H "Content-Type:application/json" -X POST --data '{"message": "sunshine"}' http://localhost:8000/
-d/--data <data> 参数
HTTP POST方式传送数据。
-d 选项是以使用 POST 方式向 Server 发送数据,因此在使用 -d 的时候,可以省略 -X POST。
请注意,使用 -d 时,将使用 Content-type:application/x-www-form-urlencoded 方式发送数据。
如果想使用 JSON 形式 post 数据,可以使用 -H 指定头部类型。
如:curl -H "Content-Type:application/json" -d '{"data":"123","key":"456"}' http://localhost:8080/search
-H/--header <line> 参数
自定义头信息传递给服务器。
例:curl -H "Host:192.168.0.1" -H "accept-language:zh-cn" URL
-c/--cookie-jar <file> 参数
操作结束后把 cookie 写入到这个文件中。
例:curl -d "name=zhangsan&password=123" http://localhost:8080/login -c ./cookie
-b/--cookie <name=string/file> 参数
cookie 字符串或文件读取位置
例:# cookie 文件
curl http://localhost:8080/login -b ./cookie
# 直接指定 cookie
curl --cookie "name=zhangsan" http://localhost:8080/login
-F/--form <name=content>/--form-string <name=string> 参数
模拟 http 表单提交数据,curl 可以通过-F命令来以Content-Type:multipart/form-data的形式向 server post 数据,
该命令允许提交二进制文件等。可以使用@前缀来制定提交的内容为一个文件,也可以使用<符号来提交文件中的内容。
例:# 向服务器上传一个图片,图片的表单 name 为 profile,内容为 protrait.jpg 的二进制
curl -F prefile=@portrait.jpg https://example.com/upload
-O/--remote-name
把输出写到该文件中,保留远程文件的文件名。
例:curl http://man.linuxde.net/text.iso --silent -O
-o/--output
把输出写到指定文件中。
例:# 选项 -o 将下载数据写入到指定名称的文件中,并使用 --progress 显示进度条:
curl http://man.linuxde.net/test.iso -o filename.iso --progress
######################################### 100.0%
-s/--silent 命令
静默模式,不输出任何东西。
curl http://man.linuxde.net/text.iso --silent -O
-i/--include
输出时包括 response 头信息
例:curl -i https://www.baidu.com
-I/--head
只显示请求头信息
例:curl -I https://www.baidu.com
其他参考写法:nginx配置开启跨域访问
由于浏览器同源策略的存在使得一个源中加载来自其它源中资源的行为受到了限制。即会出现跨域请求禁止。
通俗一点说就是如果存在协议、域名、端口或者子域名不同服务端,或一者为IP地址,一者为域名地址
(在跨域问题上,域仅仅是通过"url的首部"来识别而不会去尝试判断相同的IP地址对应着两个域或者两个域是否同属同一个IP),
之中任意服务端旗下的客户端发起请求其它服务端资源的访问行动都是跨域的,而浏览器为了安全问题一般都限制了跨域访问,也就是不允许跨域请求资源。
但很多时候我们却又不得不去跨域请求资源,这个时候就需要我们想方法去绕过浏览器同源策略的限制了。
常见的跨域请求解决方法:
1.Jsonp 利用script标签发起get请求不会出现跨域禁止的特点实现
2.window.name+iframe 借助中介属性window.name实现
3.Cors需要服务器设置header:Access-Control-Allow-Origin
4.Nginx反向代理 可以不需要目标服务器配合,不过需要Nginx中转服务器,用于转发请求(服务端之间的资源请求不会有跨域限制)
利用Nginx可以最简单且高效解决跨域问题。
跨域是前后端分离开发中非常常见的问题。这个问题网上已经有非常多的答案,但大部分是编程框架里面添加CORS头。
但无论用什么Web框架,现已很难离开Nginx。因此直接在Nginx中处理跨域问题有得天独厚的优势,可以将OPTIONS请求拦截在API服务之前,
节约服务器开销。
简单说,跨域分为简单跨域和复杂跨域。
简单跨域不会发送OPTIONS请求。
复杂跨域会发送一个预检查OPTIONS请求。
复杂跨域的条件是:
非GET、HEAD、POST请求。
POST请求的Content-Type不是application/x-www-form-urlencoded, multipart/form-data, 或text/plain。
添加了自定义header,例如Token。
跨域请求浏览器会在Headers中添加Origin,通常情况下不允许用户修改其值。
log_format nginx_log '[$time_local] - $msec - $remote_addr - $request_body - $arg_username - $arg_passwd';
location /xx
{
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET,POST,PUT,DELETE,PATCH,OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
if ($request_method = 'OPTIONS')
{
return 204;
}
lua_need_request_body on;
content_by_lua 'local body = ngx.var.request_body';
access_log /home/data/nginx/logs/nginx.log nginx_log;
}
(get请求:成功返回跨域头)
curl -I -X GET 'http://cdh06:80/xx?username=clannad&passwd=air' # -X GET 可省略
HTTP/1.1 200 OK
Server: nginx/1.17.0
Date: Thu, 08 Aug 2019 05:47:14 GMT
Content-Type: application/octet-stream
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET,POST,PUT,DELETE,PATCH,OPTIONS
Access-Control-Allow-Headers: DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization
(OPTIONS预检请求成功返回跨域头)
curl -I -X OPTIONS 'http://cdh06:80/xx?username=clannad&passwd=air'
HTTP/1.1 204 No Content
Server: nginx/1.17.0
Date: Thu, 08 Aug 2019 05:51:48 GMT
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET,POST,PUT,DELETE,PATCH,OPTIONS
Access-Control-Allow-Headers: DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization
配置示例
server {
listen 80;
server_name _;
charset utf-8;
location / {
if ($http_origin ~ '^http(s)?://(localhost|www.你的域名.com)$') {
add_header 'Access-Control-Allow-Origin' "$http_origin" always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Accept, Authorization, Cache-Control, Content-Type, DNT, If-Modified-Since, Keep-Alive, Origin, User-Agent, X-Requested-With, Token, x-access-token' always;
}
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' "$http_origin" always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Accept, Authorization, Cache-Control, Content-Type, DNT, If-Modified-Since, Keep-Alive, Origin, User-Agent, X-Requested-With, Token, x-access-token' always;
# Tell client that this pre-flight info is valid for 20 days
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
proxy_http_version 1.1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://127.0.0.1:8080;
proxy_redirect off;
}
}
CRUL跨域测试
GET请求成功返回跨域头:
➜ ~ curl -I -H "Origin: http://localhost" http://localhost
HTTP/1.1 403 Forbidden
Server: nginx/1.15.6
Date: Wed, 14 Nov 2018 07:56:01 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 153
Connection: keep-alive
Access-Control-Allow-Origin: http://localhost
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Accept, Authorization, Cache-Control, Content-Type, DNT, If-Modified-Since, Keep-Alive, Origin, User-Agent, X-Requested-With, Token, x-access-token
OPTIONS预检请求成功返回跨域头:
➜ ~ curl -I -H "Origin: http://localhost" -X OPTIONS http://localhost
HTTP/1.1 204 No Content
Server: nginx/1.15.6
Date: Wed, 14 Nov 2018 08:19:36 GMT
Connection: keep-alive
Access-Control-Allow-Origin: http://localhost
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Accept, Authorization, Cache-Control, Content-Type, DNT, If-Modified-Since, Keep-Alive, Origin, User-Agent, X-Requested-With, Token, x-access-token
Access-Control-Max-Age: 1728000
Content-Type: text/plain charset=utf-8
Content-Length: 0
备注: 如果服务器端代码中设置了允许跨域,使用Nginx代理里面就不需要了
Nginx跨域访问解决方案
1.使用Ajax跨域请求资源,Nginx作为代理,出现以下错误:
The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed
2.解决方法:
使用Nginx作为反向代理服务器,并在配置中对应的location下添加上如下的设置
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header Cache-Control private;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
完整配置如下:
server {
listen 80;
server_name 192.168.16.190;
root /home/fastdfs/file/data;
index index.htm index.html;
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header Cache-Control private;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
location / {
# 此处用于处理 H5 的 History时 重写的问题
if (!-e $request_filename) {
rewrite ^(.*) /index.html last;
break;
}
}
# 代理服务端接口
location /api {
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,PATCH,OPTIONS;
return 200;
}
proxy_pass http://192.168.16.191:3000/api; #将真正的请求代理到API 服务地址
}
location ^~/cross_origin/ {
rewrite ^/cross_origin/(.*)$ /$1 break;
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,PATCH,OPTIONS;
return 200;
}
proxy_pass http://192.168.16.191:3000/cross_origin ; #将真正的请求代理到API 服务地址
}
}
备注: 如果服务器端代码中设置了允许跨域,使用Nginx代理里面就不需要了
服务端端代码中 允许跨域配置:
#region 设置允许跨域,允许复杂请求
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,PATCH,OPTIONS");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization");
//HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
HttpContext.Current.Response.End();
}
#endregion
Nginx配置跨域请求 Access-Control-Allow-Origin *
当出现403跨域错误的时候 No 'Access-Control-Allow-Origin' header is present on the requested resource,
需要给Nginx服务器配置响应的header参数。
解决方案:
只需要在Nginx的配置文件中配置以下参数:
location /
{
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
if ($request_method = 'OPTIONS')
{
return 204;
}
}
参数属性解释:
1.Access-Control-Allow-Origin
服务器默认是不被允许跨域的。给Nginx服务器配置`Access-Control-Allow-Origin *`后,表示服务器可以接受所有的请求源(Origin),
即接受所有跨域的请求。
2.Access-Control-Allow-Headers
Access-Control-Allow-Headers 是为了防止出现以下错误:
Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
在预检响应中,Access-Control-Allow-Headers 不允许请求头字段Content-Type
这个错误表示当前请求Content-Type的值不被支持。其实是我们发起了"application/json"的类型请求导致的。
这里涉及到一个概念:预检请求(preflight request),请看后面的"预检请求"的介绍。
3. Access-Control-Allow-Methods 是为了防止出现以下错误:
Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
4.给OPTIONS 添加 204的返回,是为了处理在发送POST请求时Nginx依然拒绝访问的错误
发送"预检请求"时,需要用到方法 OPTIONS ,所以服务器需要允许该方法。
204——请求收到,但返回信息为空
意思等同于请求执行成功,但是没有数据,浏览器不用刷新页面.也不用导向新的页面。如何理解这段话呢。
还是通过例子来说明吧,假设页面上有个form,提交的url为http-204.htm,提交form,正常情况下,页面会跳转到http-204.htm,
但是如果http-204.htm的相应的状态码是204,此时页面就不会发生转跳,还是停留在当前页面。
另外对于a标签,如果链接的页面响应码为204,页面也不会发生跳转。
所以对于一些提交到服务器处理的数据,只需要返回是否成功的情况下,可以考虑使用状态码204(也就是XMLHttpRequest.status)
来作为返回信息,从而省掉多余的数据传输。
HTTP/204响应
会话列表中的第二条会话返回了HTTP/204响应.从Content-Length响应头可以看出,该响应没有响应体,状态码描述为“No Content”:
你也许会有疑问:“返回一个没有响应体的HTTP/200响应不行吗?”
如果没有响应体,则在大多数场景下,这两种响应码完全等效,但有一种情况下,HTTP/204响应会让浏览器有不同的表现.
这种情况就是当用户在浏览器窗口window或者frame/iframe框架中导航的时候.
如果导航到的URL返回了一个没有响应体的HTTP/200响应,则页面将会显示一个空白文档(就是一片白色).页面的URL地址也会变成新指定的URL.
如果服务器返回的是一个HTTP/204响应,当前页面不会有任何变化,就好像根本没有进行导航操作一样.页面的URL地址也保持不变.
HTTP/205响应码很少见,它类似于HTTP/204,除了页面保留在当前文档不变以外,多了一步操作,就是要清空当前文档内所有表单控件的内容.
预检请求(preflight request)
1.其实上面的配置涉及到了一个W3C标准:CROS,全称是跨域资源共享 (Cross-origin resource sharing),它的提出就是为了解决跨域请求的。
跨域资源共享(CORS)标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站有权限访问哪些资源。
另外,规范要求,对那些可能对服务器数据产生副作用的HTTP 请求方法(特别是 GET 以外的 HTTP 请求,
或者搭配某些 MIME 类型的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),
从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,
服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies 和 HTTP 认证相关数据)。
2.其实Content-Type字段的类型为application/json的请求就是上面所说的搭配某些 MIME 类型的 POST 请求,
CORS规定,Content-Type不属于以下MIME类型的,都属于预检请求:
application/x-www-form-urlencoded
multipart/form-data
text/plain
3.所以 application/json的请求 会在正式通信之前,增加一次"预检"请求,
这次"预检"请求会带上头部信息 Access-Control-Request-Headers: Content-Type
OPTIONS /api/test HTTP/1.1
Origin: http://foo.example
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type
... 省略了一些
4.服务器回应时,返回的头部信息如果不包含 Access-Control-Allow-Headers: Content-Type 则表示不接受非默认的的Content-Type。
即出现以下错误:Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
在预检响应中,Access-Control-Allow-Headers 不允许请求头字段Content-Type
nginx优化配置
=================== 查看linux cpu核数 =========================
# 总核数 = 物理CPU个数 X 每颗物理CPU的核数
# 总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数
# 查看物理CPU个数。node7有2个CPU,每个cpu的核数为8个,一共有16个核
cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l
或grep 'physical id' /proc/cpuinfo | sort -u | wc -l
# 查看每个物理CPU中core的个数(即核数)。node7有2个CPU,每个cpu的核数为8个,一共有16个核
cat /proc/cpuinfo| grep "cpu cores"| uniq
或者grep 'core id' /proc/cpuinfo | sort -u | wc -l
# 查看逻辑CPU的个数
cat /proc/cpuinfo| grep "processor"| wc -l
或者grep 'processor' /proc/cpuinfo | sort -u | wc -l
# 查看CPU信息(型号)
cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c
或者dmidecode -s processor-version
#查看内 存信息
cat /proc/meminfo
#总核数 = 物理CPU个数 X 每颗物理CPU的核数
#总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数
#node7有2个CPU,每个cpu的核数为8个,一共有16个核
[root@cdh07 etl]# cat /proc/cpuinfo| grep "cpu cores"| uniq
cpu cores : 8
[root@cdh07 etl]# cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l
2
================== 性能优化 ====================
#默认启动1个master process,然后根据worker_processes配置的个数启动同样对应个数的worker process
#设置Nginx 启动多少个worker process工作进程的数量,数值不能超过CPU的总核数
#worker_processes最多开启8个,8个以上性能提升不会再提升了,而且稳定性变得更低,所以8个进程够用了。
worker_processes 8;
#固定Nginx 工作进程所运行的CPU核心
#0001表示启用第一个CPU内核,0010表示启用第二个CPU内核,依此类推;worker_processes最多开启8个,8个以上性能提升不会再提升了,而且稳定性变得更低,所以8个进程够用了。
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
#1.nginx默认是没有开启利用多核cpu的配置的。需要通过增加worker_cpu_affinity配置参数来充分利用多核cpu,cpu是任务处理,
# 当计算最费时的资源的时候,cpu核使用上的越多,性能就越好。
#2.配置完之后可以重启nginx,用ab工具或者wrk工具,可以进行性能测试,在服务器上执行top,然后按1,就可以看到cpu工作情况,
# 如果多个cpu内核的利用率差不多,就证明nginx已经成功利用了多核cpu,测试结束后,cpu内核的负载都同时降低。
#3.2核是 01,四核是0001,8核是00000001,有多少个核,就有几位数,1表示该内核开启,0表示该内核关闭。
# 0001表示启用第一个CPU内核,0010表示启用第二个CPU内核,依此类推;
# worker_processes最多开启8个,8个以上性能提升不会再提升了,而且稳定性变得更低,所以8个进程够用了。
#2核cpu,开启2个进程。01表示启用第一个CPU内核,10表示启用第二个CPU内核,第一个进程对应着第一个CPU内核,第二个进程对应着第二个CPU内核。
worker_processes 2;
worker_cpu_affinity 01 10;
#2核cpu,开启4个进程。开启了四个进程,它们分别对应着开启2个CPU内核
worker_processes 4;
worker_cpu_affinity 01 10 01 10;
#4个cpu,开启4个进程。0001表示启用第一个CPU内核,0010表示启用第二个CPU内核,依此类推
worker_processes 4;
worker_cpu_affinity 0001 0010 0100 1000;
#4核cpu,开启2个进程。0101表示开启第一个和第三个内核,1010表示开启第二个和第四个内核;2个进程对应着四个内核;
#worker_cpu_affinity配置是写在/etc/nginx/nginx.conf里面的;2核是 01,四核是0001,8核是00000001,有多少个核,就有几位数,1表示该内核开启,0表示该内核关闭。
worker_processes 2;
worker_cpu_affinity 0101 1010;
#8核cpu,开启8个进程。0001表示启用第一个CPU内核,0010表示启用第二个CPU内核,依此类推;
#worker_processes最多开启8个,8个以上性能提升不会再提升了,而且稳定性变得更低,所以8个进程够用了。
worker_processes 8;
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
#配置nginx工作进程最大打开文件数:可以设置为linux系统最大打开的文件数量一致,在全局模块配置
#cat /proc/sys/fs/file-max 查看系统级的最大限制
#ulimit -n 查看用户级的限制(一般是1024,向阿里云华为云这种云主机一般是65535)
#vim /etc/security/limits.conf 中永久配置
worker_rlimit_nofile Nginx最大可用文件描述符数量; # 65535
#网络连接的优化:只能在events模块设置,用于防止在同一一个时刻只有一个请求的情况下,出现多个睡眠进程会被唤醒但只能有一个进程可获得请求的尴尬,
#如果不优化,在多进程的nginx会影响以部分性能。
events {
accept_mutex on; #优化同一时刻只有一个请求而避免多个睡眠进程被唤醒的设置,on为防止被同时唤醒,默认为off,因此nginx刚安装完以后要进行适当的优化。
}
#设置是否允许同时接受多个网络连接:只能在events模块设置,Nginx服务器的每个工作进程可以同时接受多个新的网络连接,但是需要在配置文件中配置,此指令默认为关闭,
#即默认为一个工作进程只能一次接受一个新的网络连接,打开后几个同时接受多个,配置语法如下:
events {
accept_mutex on;
multi_accept on; #打开同时接受多个新网络连接请求的功能。
}
#选择事件驱动模型:Nginx支持众多的事件驱动,比如select、poll、epoll,只能设置在events模块中设置:
events {
accept_mutex on;
multi_accept on;
use epoll; #使用epoll事件驱动,因为epoll的性能相比其他事件驱动要好很多
}
worker_connections:
官方解释如下,个人认为是每一个worker进程能并发处理(发起)的最大连接数(包含所有连接数)。
不能超过最大文件打开数:在linux终端中输入ulimit -a进行查看信息:open files (-n) 1024 表示默认1024个
#配置单个工作进程的最大连接数:通过worker_connections number; 进行设置,numebr为整数,number的值不能大于操作系统能打开的最大的文件句柄数,
#使用ulimit -n可以查看当前操作系统支持的最大文件句柄数,默认为为1024.
events {
worker_connections 102400; #设置单个工作进程最大连接数102400
accept_mutex on;
multi_accept on;
use epoll;
}
#值不能大于操作系统能打开的最大的文件句柄数,使用ulimit -n可以查看当前操作系统支持的最大文件句柄数,默认为为1024.
#配置单个Nginx单个进程可服务的客户端数量,(最大值客户端数 = 单个进程链接数据 * 进程数),最大客户端数同时也受操作系统socket链接数的影响(最大64K)
events
{
worker_connections 配置单个工作进程的最大连接数;
accept_mutex on;
multi_accept on; #运行尽可能的处理更多的链接数,如果worker_connections配置太低,会产生大量的无效链接请求
use epoll; #允许单个线程处理多个客户端请求
}
#开启sendfile选项,使得内核的FD文件传输功能,这个比用户态用read()+write()的方式更高效
#sendfile参数用于开启文件的高效传输模式。同时将tcp_nopush和tcp_nodelay两个指令设置为on,可防止网络及磁盘i/o阻塞,提升nginx工作效率。
#配置允许sendfile方式传输文件:是由后端程序负责把源文件打包加密生成目标文件,然后程序读取目标文件返回给浏览器;
#这种做法有个致命的缺陷就是占用大量后端程序资源,如果遇到一些访客下载速度巨慢,就会造成大量资源被长期占用得不到释放(如后端程序占用的CPU/内存/进程等),
#很快后端程序就会因为没有资源可用而无法正常提供服务。通常表现就是 nginx报502错误,而sendfile打开后配合location可以实现有nginx检测文件使用存在,
#如果存在就有nginx直接提供静态文件的浏览服务,因此可以提升服务器性能。
#可以配置在http、server或者location模块,配置如下:
sendfile on;
sendfile_max_chunk 512k; #Nginx 工作进程每次调用sendfile()传输的数据最大不能超出这个值,默认值为0表示无限制,可以设置在http/server/location模块中。
#激活tcp_nopush参数可以允许把http response header和文件的开始放在一个文件里发布,积极的作用是减少网络报文段的数量(只有sendfile on开启才生效)
#打开tcp_nopush选项,Nginx允许将HTTP应答首部与数据内容在用一个报文中发出。这个选项使服务器在sendfile时可以提前准备HTTP首部,能够达到优化吞吐的效果。
tcp_nopush on;
#不要缓存data-sends(关闭Nagle算法),这个能提高高频发送小数据报文的实时性。
tcp_nodelay on;
#配置链接keep-alive超时时间,服务器将在超时之后关闭相应的链接。
keepalive_timeout 30;
#单个客户端在keep-alive链接上可以发送的请求数量。在测试和压测的环境中,需要配置一个较大的值
keepalive_requests 10000;
#允许服务器在停止发送应答之后关闭连接,以便释放链接相应的socket内存开销。
reset_timedout_connection on;
#配置客户端数据请求超时时间,默认时60s
client_body_timeout 10;
#客户端数据读超时配置,客户端停止读取数据,超时时间后断开相应的链接,默认时60s
send_timeout 2
#隐藏ngxin版本号:
#当前使用的nginx可能会有未知的漏洞,如果被黑客使用将会造成无法估量的损失,但是我们可以将nginx的版本隐藏,如下:
server_tokens off; #在http 模块当中配置
1、keepalive_timeout 60 50;
#设置Nginx服务器与客户端保持连接的时间是60秒,到60秒后服务器与客户端断开连接,50s是使用Keep-Alive消息头与部分浏览器如 chrome等的连接事件,
到50秒后浏览器主动与服务器断开连接。
keepalived_timeout 60 50;
2、send_timeout 10s
#Http核心模块指令,指定了发送给客户端应答后的超时时间,Timeout是指没有进入完整established状态,只完成了两次握手,
如果超过这个时间客户端没有任何响应,nginx将关闭与客户端的连接。
sendtime_out 10s;
3、client_header_timeout
#客户端向服务端发送一个完整的 request header 的超时时间。如果客户端在指定时间内没有发送一个完整的 request header,Nginx 返回 HTTP 408(Request Timed Out)。
# 配置位置: http, server, location
client_header_timeout 10s;
4、multi_accept
#设置是否允许,Nginx在已经得到一个新连接的通知时,接收尽可能更多的连接。
multi_accept on;
http
{
sendfile on;
tcp_nopush on;
tcp_nodelay on;
server_tokens off;
server_names_hash_bucket_size 128;
server_names_hash_max_size 512;
keepalive_timeout 65;
client_header_timeout 15s;
client_body_timeout 60s;
send_timeout 60s;
}
#配置网络监听:使用命令listen,可以配置监听IP+端口,端口或监听unix socket:
listen 8090; #监听本机的IPV4和IPV6的8090端口,等于listen *:8000
listen 192.168.0.1:8090; #监听指定地址的8090端口
listen Unix:/www/file #监听unix socket
跨域解决方案:CORS
1.跨域解决的两种方案:CORS(推荐)、JSONP。
2.CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。CORS需要浏览器和服务器同时支持。
目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。
浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。
因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。
跨域请求调用时,实际会发送两次请求:
第一次:浏览器先发预请求,服务器返回预响应
第二次:浏览器发送真正请求,服务器返回真正响应
Access-Control-Allow-Origin 是 HTML5中定义的一种解决资源跨域的策略。
通过服务器端返回带有Access-Control-Allow-Origin标识的Response header,用来解决资源的跨域权限问题。
服务器中需要在响应对象中添加以下的响应头信息:表示浏览器可以发送跨域请求 进行跨域访问“协议://域名(IP地址):端口”
1.浏览器发出跨域请求进行跨域访问,比如:
1.业务要求:在pinyougou-page-web工程(localhost:9105)中的页面中,通过浏览器发出跨域请求,
要进行跨域访问“pinyougou-cart-web工程(localhost:9107)”。
2.实现方法:在pinyougou-page-web工程(localhost:9105)中的页面中,所进行跨域访问的AJAX请求的格式为:
$http.get('http://localhost:9107/请求路径.do?参数=值,{'withCredentials':true})
3.实现原理:必须在AJAX请求中打开withCredentials属性。否则,即使服务器同意发送Cookie,浏览器也不会发送。
或者,服务器要求设置Cookie,浏览器也不会处理。
2.在“接收跨域请求访问/被跨域访问”的服务器中的响应对象中添加以下响应头信息,比如:
1.业务要求:在pinyougou-page-web工程(localhost:9105)中的页面中,通过浏览器发出跨域请求,
要进行跨域访问“pinyougou-cart-web工程(localhost:9107)”。
2.实现方法:(“接收跨域请求访问/被跨域访问”的pinyougou-cart-web工程(localhost:9107)中的响应对象中,添加以下的响应头信息)
1.第一步:
1.格式一:response.setHeader("Access-Control-Allow-Origin", "协议://域名(IP地址):端口")
“域名(IP地址):端口”代表的是指定的“发出跨域请求的所属的”服务器,
意思即允许该指定的“域名(IP地址):端口”的服务器跨域访问过来当前的服务器
2.格式二:response.setHeader("Access-Control-Allow-Origin", "*")
"*" 允许任何的“域名(IP地址):端口”的服务器访问过来当前的服务器
注意:当前格式二不能和“response.setHeader("Access-Control-Allow-Credentials", "true")”一起使用,
只有格式一和“response.setHeader("Access-Control-Allow-Credentials", "true")”可以一起使用。
3.实现例子:
pinyougou-cart-web工程(localhost:9107)中的响应对象中设置:
response.setHeader("Access-Control-Allow-Origin", "http://localhost:9105");
“localhost:9105”代表的是“发出跨域请求的所属的”pinyougou-page-web工程(localhost:9105),
表示pinyougou-cart-web工程(localhost:9107)接受pinyougou-page-web工程(localhost:9105)发出的跨域请求的访问。
2.第二步:
1.格式:response.setHeader("Access-Control-Allow-Credentials", "true");
CORS请求默认不发送Cookie和HTTP认证信息。如果要把Cookie发到服务器,一方面要服务器同意,
指定Access-Control-Allow-Credentials字段。另一方面,开发者必须在AJAX请求中打开withCredentials属性。
否则,即使服务器同意发送Cookie,浏览器也不会发送。或者,服务器要求设置Cookie,浏览器也不会处理。
2.实现例子:
pinyougou-cart-web工程(localhost:9107)中的响应对象中设置:
response.setHeader("Access-Control-Allow-Credentials", "true");
跨域解决方案:tomcat 7服务器跨域问题解决
没有允许跨域时,显示信息 No 'Access-Control-Allow-Origin' 的话,可进行tomcat服务器的跨域配置。
打开tomcat安装目录中 conf 目录下的 web.xml文件,将以下代码复制到web.xml文件中(可在 460左右的位置,不要放在最前面和最后面,一定要放中间),然后重启服务器。
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.origins</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.methods</param-name>
<param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.exposed.headers</param-name>
<param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
</init-param>
<init-param>
<param-name>cors.support.credentials</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
最后
以上就是痴情御姐为你收集整理的nginx 配置获取GET请求参数、POST请求参数、nginx配置开启跨域访问、nginx+keepalived配置主备切换/双机热备、nginx优化配置日萌社nginx+keepalived 配置 主备切换/双机热备 其他参考写法:nginx 配置获取GET请求参数、POST请求参数其他参考写法:nginx配置开启跨域访问nginx优化配置跨域解决方案:CORS跨域解决方案:tomcat 7服务器跨域问题解决的全部内容,希望文章能够帮你解决nginx 配置获取GET请求参数、POST请求参数、nginx配置开启跨域访问、nginx+keepalived配置主备切换/双机热备、nginx优化配置日萌社nginx+keepalived 配置 主备切换/双机热备 其他参考写法:nginx 配置获取GET请求参数、POST请求参数其他参考写法:nginx配置开启跨域访问nginx优化配置跨域解决方案:CORS跨域解决方案:tomcat 7服务器跨域问题解决所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复