zoukankan      html  css  js  c++  java
  • Nginx跨域了解及模拟和解决

    Nginx跨域

    同源策略

    何为同源:
    1.协议(http/https)相同
    2.域名(IP)相同
    3.端口相同
    详解请看我另一篇文章
    https://www.cnblogs.com/you-men/p/14054348.html

    浏览器遵循同源策略的目的

    同源策略的目的是为了保证用户信息的安全,防止恶意的网站窃取数据。此策略可以防止一个页面的
    恶意脚本(JavaScript语言编写的程序)通过该页面的文档对象模型来访问另一网页上的敏感数据。

    同源策略是必需的,否则cookie可以共享,互联网就毫无安全可言,同源策略仅适用于JavaScript脚本...
    换句话说,同源策略不适用与html标签:

    同源策略限制范围
    ·cookie、localstorage(本地存储)和indexDB(数据索引)
    ·DOM无法获得
    ·ajax请求不能发送
    同源策略规定,ajax请求只能发送给同源的网址,否则就报错:
    NO 'Access-Control-Allow-Origin' header is present on the requested resource.

    跨域

    1.什么是跨域:当从A网址的网页代码中请求访问B网站中的数据资源的行为就称为跨域
    2.为何会产生跨域:
    目前主流的架构网站技术都是采用前后端分离
    前端只负责静态资源的提供--前端服务器
    后端只负责动态资源的提供--后端服务器
    静态资源包含:html页面,css文件,js文件,图片等
    动态资源就是数据库中的纯数据,如用户购物车中的商品,或者电商提供的产品的库存数据等..
    一个完整的页面需要静态资源与动态资源的组合
    通常前端服务器会通过自己静态页面中的js代码向后端服务器请求数据,之后把数据填充到静态页面--页面的渲染。这个过程会产生跨域

    模拟nginx跨域

    192.168.109.137 nginx 前端服务器
    192.168.109.138 nginx + uwsgi 后端服务器

    安装nginx

    rpm -ivh nginx-1.16.0-1.el7.ngx.x86_64.rpm 
    

    准备前端测试页面

    42.193.126.123 - nginx前端服务器

    wangbc.html

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>欢迎测试nginx跨域:42.193.126.123</title>
    
    <!--js引用-->
    <script
    src="https://code.jquery.com/jquery-3.3.1.min.js"
    integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
    crossorigin="anonymous">
    </script>
    
    
    <style>
    body {
     35em;
    margin: 0 auto;
    font-family: Tahoma, Verdana, Arial, sans-serif;
    }
    </style>
    </head>
    <body>
    <div id=json></div>
    <!-- img 标签直接跨域访问静态资源 -->
    <img src="http://47.94.149.143/a.jpg">
    </body>
    <script type="text/javascript">
      // AJAX 跨域请求
    $.ajax({
    type: 'get',
    url: 'http://47.94.149.143/api/json',
    dataType: 'json',
    success: function(res) {
    //转化为字符串
    data=JSON.stringify(res)
    //添加数据到页面的div标签中
    $("#json").text(data);
    },
    error: function(res) {
    console.error(res);
    }
    });
    </script>
    </html>
    

    准备后端服务器

    47.94.149.143 nginx+uwsgi后端服务器

    rpm -ivh nginx-1.16.0-1.el7.ngx.x86_64.rpm 
    
    
    配置略改~server配置文件:作为代理并作为一个静态服务器
    server {
        listen       80;
        server_name  localhost;
        access_log /var/log/nginx/host.access_localhost.log main;
        location / {
            include uwsgi_params;
            uwsgi_pass 127.0.0.1:8000;
        }
        location ~* .(gif|jpg|jpeg|js)$ {
            root /static;
        }
    }
    
    # 创建静态文件目录/static并上传a.jpg图片
    mkdir /static
    ls /static/a.jpg
    

    安装配置uwsgi

    yum -y install epel-release python2-devel python2-pip
    
    # 使用pip安装uwsgi
    
    pip install --trusted-host pypi.org --trusted-host files.pythonhosted.org uwsgi -i https://pypi.tuna.tsinghua.edu.cn/simple
    
    # 创建应用程序目录
    mkdir -pv /opt/webapp
    cd /opt/webapp
    # 进入应用程序目录并创建应用程序文件app.py
    
    headers=('Content-Type', 'application/json;charset=utf-8')
    def application(env, start_response):
        if env[ 'PATH_INFO' ] == '/api/json':
            start_response('200 ok', [headers])
            data = '{"name": "shark", "age": 18}'
            return [data]
    
    
    # 继续在应用程序目录创建uwsgi的配置文件wbc-uwsgi.ini,添加如下内容
    vim wbc-uwsgi.ini
    [uwsgi]
    socket = 0.0.0.0:8000
    chdir = /opt/webapp
    wsgi-file = app.py
    processes = 2
    threads = 2
    
    # 启动服务
    cd /opt/webapp
    nohup uwsgi wbc-uwsgi.ini &
    
    # 启动nginx
    systemctl restart nginx
    
    # 检查端口
    ss -ntal | grep 80
    

    解决AJAX跨域请求

    有哪些方法:
    1.JSONP
    2.WebSocket
    3.CORS

    模拟由于跨域访问导致的浏览器报错,在nginx代理服务器上设置相应参数解决
    CORS是跨源资源共享(Cross-Origin Resource Sharing)的缩写,W3C标准,是跨源AJAX请求的根本解决方法。
    CORS需要浏览器和服务器同时支持。目前所有浏览器都支持该功能,IE不能低于IE10
    整个CORS通信过程,都是浏览器自动完成
    浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会感知

    两种请求

    浏览器将 CORS 请求分为两类:简单请求(simple request) 和 非简单请求(not-so-simple request)
    ** 只要同时满足以下两大条件,就属于简单请求。否则就是非简单请求。**

    1.请求方法是以下三种方法之一:
    ·HEAD
    ·GET
    ·POST

    2.HTTP的头信息不超出以下几个字段:
    · Accept
    · Accept-Language
    · Content-Language
    · Last-Event-ID
    · Content-Type:只限于三个值 application/x-www-form-urlencoded、multipart/form-data、text/plain

    浏览器对简单请求与非简单请求的处理,是不一样的。

    简单请求

    分析简单请求:
    对于简单请求,浏览器直接发出CORS请求,具体来说就是在头信息中增加一个Origin字段

    解决问题:
    后端服务器47.94.149.143 nginx允许跨域,nginx配置增加
    add_header Access-Control-Allow-Origin *;

    [root@master1 webapp]# cat /etc/nginx/conf.d/default.conf
    server {
        listen       80;
        server_name  localhost;
        access_log /var/log/nginx/host.access_localhost.log main;
        add_header Access-Control-Allow-Origin *;
        location / {
            include uwsgi_params;
    	uwsgi_pass 127.0.0.1:8000;
        }
        location ~* .(gif|jpg|jpeg|js)$ {
    	root /static;
        }
    }
    

    非简单请求

    浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求
    如有在post请求时会多出一次附加的请求OPTIONS

    if ($request_method = OPTIONS) {
    add_header Access-Control-Allow-Origin '*';
    add_header Access-Control-Allow-Methods '*';
    add_header Access-Control-Allow-Credentials true;
    add_header 'Access-Control-Allow-Headers' "Referer,resourceId,sid,Sec-Fetch-Dest,Timestamp,Signature,Request-Id,userId,DNT,web-token,app-token,Authoriz
    ation,Accept,Origin,Keep-Alive,User-Agent,x-user-agent,X-Mx-ReqToken,X-Data-Type,X-Auth-Token,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range";
    add_header 'Access-Control-Expose-Headers' 'X-Log,X-Reqid';
    add_header Access-Control-Request-Headers Origin,X-Requested-With,content-Type,Accept,Authorization;
    add_header Access-Control-Max-Age 1728000;
    return 200;
    }
    
    add_header 'Access-Control-Allow-Origin' '*' always;
    add_header 'Access-Control-Allow-Credentials' 'true';
    add_header 'Access-Control-Max-Age' '1000' always;
    add_header 'Access-Control-Allow-Methods' "POST, GET, OPTIONS, DELETE, PUT" always;
    
    add_header 'Access-Control-Allow-Headers' "Referer,resourceId,sid,Sec-Fetch-Dest,Timestamp,Signature,Request-Id,userId,DNT,web-token,app-token,Authorization,Ac
    cept,Origin,Keep-Alive,User-Agent,x-user-agent,X-Mx-ReqToken,X-Data-Type,X-Auth-Token,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range";
    add_header 'Access-Control-Expose-Headers' 'X-Log,X-Reqid';
    

    备注:Access-Control-Allow-Headers允许字段需开发提供,一起联调设置
    Access-Control-Allow-Origin允许的域名可以是*,也可以具体

    set $cors_origin "";
    
    if ($http_origin ~* "^http://base.hjq.komect.com$") {
    set $cors_origin $http_origin;
    }
    if ($http_origin ~* "^https://base.hjq.komect.com$") {
    set $cors_origin $http_origin;
    }
    add_header 'Access-Control-Allow-Origin' $cors_origin always;
    
  • 相关阅读:
    centos7 hbase 搭建笔记
    【转】python 2.6.6升级到python 2.7.x版本的方法
    centos7 sqoop 1 搭建笔记
    centos7 hive + 远程mysql 搭建笔记
    docker 批量操作容器
    centos7 hdfs yarn spark 搭建笔记
    【转】mysql查看表空间占用情况
    【转】Centos 7 修改主机名hostname
    jQuery选择
    jQuery检查复选框是否被选
  • 原文地址:https://www.cnblogs.com/you-men/p/14981032.html
Copyright © 2011-2022 走看看