-
java过滤器不能对跨域请求无效
2019-07-17 16:01:51我开启的是调试模式。我自己的请求进来就进了过滤器(在断点处停顿)。但是前端的人发送的请求就完全没有进入过滤器(没在断点处停顿),并且获得了响应。 -
JQuery的Ajax跨域请求要义
2013-06-29 15:57:39今天自己用java写了一个servlet,自运行一个服务开启8080端口,然客户端利用ajax 发post请求调用8080端口servlet。代码片段大致如下: $.ajax({ type: "post", url: "Default.aspx",今天自己用java写了一个servlet,自运行一个服务开启8080端口,然客户端利用ajax 发post请求调用8080端口servlet。代码片段大致如下:
$.ajax({
type: "post",
url: "Default.aspx",
dataType: "text",data: 'username='+username+'&password='+password,
success: function (data) {
alert(data)
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(errorThrown);
}
});在ie、ff、chrome三大浏览器上测试,ie完全没有反映,ff和chrome执行的时候,发现后台其实是调用servlet,后台有东西输出。在网上查询,说是涉及到跨域访问,于是我将js所在的网页放到8080服务器下执行,三大浏览器访问,果然均返回“sucess”。说明问题确实是跨域造成的。
有文章说利用jsnop解决跨域问题。经过一番折腾,终于调通了,现总结如下,利用jsnop方式代码如:
要素一:dataType改成JSONP,必须要追加jsonp: "callbackparam",callbackparam可以自定义。这个是传给后台用的回调函数名字(是个参数),jsonpCallback写不写无所谓,不写的话,程序会随机生成一个函数名,如jQuery1720565933280158788_1372490746392,如果定义了,程序就会用定义的名字,如下面例子success_jsonpCallback。
$.ajax({ //一个Ajax过程
type: "post", //以post方式与后台沟通
url : "http://localhost:8080/LoadClas/loadcls", //与此php页面沟通
dataType:'JSONP',//从php返回的值以 JSON方式 解释
data: 'username='+username+'&password='+password,
jsonp: "callbackparam",//服务端用于接收callback调用的function名的参数
jsonpCallback:"success_jsonpCallback",//callback的function名称
success: function(json){//如果调用php成功
alert(json[0].msg)
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(errorThrown);
}
});要素二:后台要jsonp: "callbackparam"值获得。
String callbackparam = request.getParameter("callbackparam");
要素三:返回值要是json串
格式必须是:String jsonString = callbackparam + "([{'key':'value'}])" 这种形式。
这里需要特别注意的是很多文章都没有说清楚ajax参数里jsonp和jsonpCallback是怎么回事。
就我个人的从程序的理解来解释的话,之所以定义这两个参数,是为了给后台拼装json格式规则做准备。参见我的要素三,json前缀callbackparam就是通过这两个参数获得的。jsonp定义了request的key,即request.getParameter("callbackparam");jsonpCallback定义了key对应的value值,即success_jsonpCallback。所以ajax向后台请求的时候,原理上地址是“XXX.do?callbackparam=success_jsonpCallback&username=aaa&password=bbb”。
如果没有定义jsonpCallback,那么如我前面所述,程序会自动生成一个随机的函数名。输出的json串类似于
success_jsonpCallback([{'bbb':'ccc'}])或
jQuery1720565933280158788_1372490746391([{'bbb':'ccc'}])
-
nginx 配置获取GET请求参数、POST请求参数、nginx配置开启跨域访问、nginx+keepalived配置主备切换/双机...
2019-08-09 23:09:20nginx 把 POST请求数据 写入到 日志文件中 nginx 自动解压gzip压缩数据的两种方式:nginx自动解压、后台java程序解压 nginx安装、nginx反向代理/负载均衡、Lua、LuaJIT、openresty、lua-nginx-module、ngx_devel_...日萌社
人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新)
nginx+keepalived:局域网内网和公网外网 搭建nginx HA 双机热备 高可用
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>
-
单点登录中ajax跨域遇到的坑
2020-05-15 16:19:361.ajax中使用跨域请求后端如果数据格式为json则每次访问都会开启不同的session,因此要将数据设置为jsonp格式。 2.jsonp格式只能发送get请求,即使你把方法设置为post,依然会以get请求发送到后端,因此后端得用...1.php后端:
php后端在进行跨域请求的时候加上 header('Access-Control-Allow-Origin:*');
2.java后端:
java后端也是设置请求头,和php类似
3.前端ajax:
1.ajax中使用跨域请求后端如果数据格式为json则每次访问都会开启不同的session,因此要将数据设置为jsonp格式。
2.jsonp格式只能发送get请求,即使你把方法设置为post,依然会以get请求发送到后端,因此后端得用get获取数据。
3.jsonp不能把数据放在请求头中。
4.使用jsonp返回的数据是通过调用自定义的函数来调用,如果你使用suceese函数调用可能取不出返回数据。
5.用ajax进行跨域请求时,如果报' token>' 这种带尖括号的错误,原因是后端返回数据格式错误,要以json形式返回数据。
6.用ajax进行跨域请求时,如果报 500 GET 之类的错误大概就是后端代码的错误。
-
python爬虫跨域_AJAX跨域简单讲解【Python版】
2020-12-08 05:58:17什么是AJAX跨域只要协议、域名、端口有任何一个不同,都被当作是不同的域,不同域之间的请求就是跨域操作。AJAX跨域就是AJAX在A域下对B域发送了请求,一般情况下会被浏览器禁止。例如,后台开启两个Flask服务器...总结自JAVA,这里改成了Python。
什么是AJAX跨域
只要协议、域名、端口有任何一个不同,都被当作是不同的域,不同域之间的请求就是跨域操作。AJAX跨域就是AJAX在A域下对B域发送了请求,一般情况下会被浏览器禁止。
例如,后台开启两个Flask服务器ServerA(port=8080)和ServerB(port=8081):
ServerA.py代码如下:
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/get')
def get():
return 'get8080 ok'
if __name__ == "__main__":
app.run(port=8080)
ServerB.py代码如下:
from flask import Flask
app = Flask(__name__)
@app.route('/get')
def get():
return 'get8081 ok'
if __name__ == "__main__":
app.run(port=8081)
index.html使用jQuery发送ajax请求,代码如下:
IndexTest
GET 8080
GET 8081
function get1(){
$.get("http://127.0.0.1:8080/get").then(
function(res){
console.log(res);
})
}
function get2(){
$.get("http://127.0.0.1:8081/get").then(
function(res){
console.log(res);
})
}
因此GET 8080和GET 8081两个按钮是分别向8080/8081端口发送请求,并将结果打印在控制台。开启两个服务器,在浏览器输入127.0.0.1:8080进入index页面,打开Chrome控制台并依次点击,结果如图:
可以看到GET 8080正常输出,而由于8081端口的请求属于跨域,浏览器报错并未正常打印结果。
如何处理AJAX跨域问题
1.关闭浏览器安全策略
禁止跨域的AJAX请求,是浏览器本身的安全策略,实际上后台并没有限制,例如点击GET 8081后,可以在NETWORK中看到这个请求本身是OK的:
因此只要关闭浏览器的安全策略即可,方式之一是在命令行中使用
"chrome.exe路径" --disable-web-security --user-data-dir=D:\temp
打开浏览器,此时浏览器会有安全性提示,依次点击两个按钮,结果如图:
2.使用JSONP
AJAX请求受到跨域的限制,其请求类型是xhr,但html页面在引用别的域的JS脚本时却可以正常访问,这种请求的类型是script,如图:
JSONP的原理就是将原本的xhr请求替换为script请求,例如假设原先xhr请求返回的是数据A,JSONP请求会附带一个callback参数说明本地使用的回调函数,假设为func1,后端收到这个JSONP请求,返回的是JS代码func1(A)。使用JSONP需要对前后端都做修改。在此不演示~
3.在ServerA中修改
我们可以让后台服务器代替浏览器去请求跨域的接口,并将数据通过本域的接口返回给浏览器,使浏览器不再发送跨域请求。例如在ServerA.py中增加一个接口如下:
@app.route('/get_8081_through_8080')
def get2():
return requests.get('http://127.0.0.1:8081/get').text
index.html增加一个button,如下:
GET 8081 THROUGH 8080
function get1(){
...
}
function get2(){
...
}
function get3(){
$.get("http://127.0.0.1:8080/get_8081_through_8080").then(
function(res){
console.log(res);
})
}
此时对浏览器而言get3()就不属于跨域的请求了,后台代替浏览器向8081发送了请求。
结果如图所示,第二个button由于跨域仍然报错,第三个button则正常输出:
4.在ServerB中修改
ServerB也可以通过向浏览器返回特定响应头,告诉浏览器它是允许被跨域调用的,使用flask的make_response添加Access-Control-Allow-Origin和Access-Control-Allow-Methods两个字段,ServerB.py更新如下:
from flask import Flask, Response
app = Flask(__name__)
@app.route('/get')
def get():
return 'get8081 ok'
@app.route('/get2')
def get2():
resp = Response('get8081 ok by Access-Control-Allow')
resp.headers['Access-Control-Allow-Origin'] = 'http://127.0.0.1:8080'
resp.headers['Access-Control-Allow-Methods'] = 'GET'
return resp
if __name__ == "__main__":
app.run(port=8081)
将index.html的get2()方法请求的接口改为'http://127.0.0.1:8081/get2',依次点击button,第二个button已经可以正常输出内容:
-
vue 和 Flask 跨域问题解决
2020-09-02 16:10:09后端如果没有开启跨域的话,会一直提示OPTIONS 的请求,或者直接无法拿到数据。因为我是运维人员,要Java开发去检查后端代码,Java开发说我的跨域开启了,是前端问题或者是运维的Nginx的问题。反正就是你推我 我推你... -
python中文乱码如何处理、如何处理跨域_AJAX跨域简单讲解【Python版】
2020-11-29 20:05:22什么是AJAX跨域只要协议、域名、端口有任何一个不同,都被当作是不同的域,不同域之间的请求就是跨域操作。AJAX跨域就是AJAX在A域下对B域发送了请求,一般情况下会被浏览器禁止。例如,后台开启两个Flask服务器... -
AJAX跨域简单讲解【Python版】
2018-05-03 16:51:14总结自慕课网:ajax跨域完全讲解,并且原视频中后台为JAVA,这里改成了Python。 什么是AJAX跨域 只要协议、域名、端口有任何一个不同,都被当作是不同的域,不同域之间的请求就是跨域操作。AJAX跨域就是AJAX在A域下... -
Java Web知识点
2020-11-25 19:51:25数据共享:foeword是一个请求的延续,可以共享request作用域的信息,redirect开启一个新请求,不可以共享request 作用域的信息,但可以通过URL的方式进行数据发送。 性能:forword性能高于redirect 在本系统请求建议... -
JAVA SpringBoot学习笔记
2020-09-25 15:40:07例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。 提示:以下是本篇文章正文内容,下面案例可供参考 一.SpringBoot常用注解 1.@... -
js调用webservice
2013-10-16 16:36:42需要设置浏览器跨域访问,google浏览器通过开始--运行chrome.exe --disable-web-security开启跨域访问。其它浏览器不知道怎么开启这个操作。此操作不安全,请慎用。[/size][/color] [code="java"] ... -
#开启跨域设置,默认false spring.emily.web.cors.enable=false #设置允许哪些源来访问,多个源用逗号分开 spring.emily.web.cors.allowed-origins= #允许HTTP请求方法 spring.emily.web.cors.allowed-methods=GET,...
-
工程硕士学位论文 基于Android+HTML5的移动Web项目高效开发探究
2017-02-28 21:22:19第三章 跨域交互缓存处理设计 17 3.1 跨域交互缓存处理需求 17 3.1.1 缓存技术WebStorage 17 3.1.2 跨域交互缓存处理需求 17 3.1.3 页面回退管理需求 17 3.2 缓存处理机制 18 3.2.1 跨域缓存处理 18 3.2.2页面回退... -
开启跨域访问功能 三、spring-boot2-rocketmq 介绍Springboot2【RocketMQ集成】的用法: 如何与springboot集成 如何建立连接,发送不同消息数据类型 如何订阅,且消费不同消息数据类型 场景案例分析 四、spring-...
-
【Solr】solr开启授权无法更新索引的四种解决方案 解决solr更新索引报错问题 200-webflux 【web】WebFlux实例 React 201-web 【web】basic http实例 springmvc 202-web-params 【web】请求参数解析的各种姿势 ...
-
Vertx怎么上传或下载文件到Nginx服务器
2019-11-09 16:00:42这是Vertx的代码、程序开启时Vertx可以启动,但是不知道怎么上传文件,求补充前端代码怎么触发上传或下载 ````java package zyxhj.utils; import java.util.HashSet; import java.util.Iterator; import java... -
XML轻松学习手册--XML肯定是未来的发展趋势,不论是网页设计师还是网络程序员,都应该及时学习和了解
2008-12-05 08:39:07面向对象的思想方法已经非常流行了,在编程语言(例如java,js)中,都运用面向对象的编程思想。在XML中,就是要将网页也作为一个对象来操作和控制,我们可以建立自己的对象和模板。与对象进行交流,如何命令对象,... -
4.1.6 JAVA8的ConcurrentHashMap为什么放弃了分段锁,有什么问题吗,如果你来设计,你如何设计。 4.1.7 有没有有顺序的Map实现类,如果有,他们是怎么保证有序的。 4.1.8 抽象类和接口的区别,类可以继承多个类么...
-
居然有人想白嫖我的日志,赶紧开启安全保护压压惊! 面对成百上千台服务器产生的日志,试试这款轻量级日志搬运神器! 还在手动部署SpringBoot应用?试试这个自动化插件! 不要再重复造轮子了,这款开源工具类库贼好...
-
前端知识体系整理(不断更新)
2020-12-27 10:25:59如<code>Java、<code>C#</code></li><li>javascript:基于原型<code>prototype的OOP,对象由构造器(构造函数)<code>constructor利用原型<code>prototype产生</li><li>生成js对象:...
-
MaxScale 实现 MySQL 读写分离与负载均衡
-
Docker从入门到精通
-
采集悟空问答的爬虫gj
-
ELF视频教程
-
PC桌面版本的APP网页内容收集分析管理工具
-
2021 年该学的 CSS 框架 Tailwind CSS 实战视频
-
cmake-3.20.0-rc1-windows-x86_64.rar
-
sqlite java blob_【转】好东西!sqlite3中BLOB数据类型存储大对象运用示例
-
MySQL 四类管理日志(详解及高阶配置)
-
【整除分块+等差数列求和】牛客练习赛77 C.小G的约数
-
推荐一个科研党的翻译神器
-
java线程倒计时_Java线程与并发编程实践----同步器(倒计时门闩,同步屏障)
-
数据库工程师 java_Java开发工程师(Web方向) - 03.数据库开发 - 期末考试
-
MySQL 高可用(DRBD + heartbeat)
-
2020-12-02版的带桌面树莓派系统镜像
-
使用 Linux 平台充当 Router 路由器
-
2021年 系统分析师 系列课
-
MySQL 主从复制 Replication 详解(Linux 和 W
-
【布道者】Linux极速入门
-
若干Java进阶资料整理,面试,教程,书籍等分享