案例cookie实现跨域


跨域,顾名思义,个人理解就是:任意两个url只要协议、域名、端口有任何一个不同,都被当作是不同的域,相互访问就会有跨域问题。


方案一(前端需要实现跨域)


例如如下这一段代码,在前端页面中调试这个ajax所在的页面,页面路径是http://localhost:8081/demo1/index.html,而要访问的接口路径是http://localhost:8082/demo2/login

$(function(){
        $.ajax({
            url: "http://localhost:8082/demo2/login",
            type: "POST",
            contentType: "application/json",
            data: JSON.stringify({
                        "name": "tomcat",
                        password:"oracle"
                    }),
            success: function(data) {
               alert("success")
            },
        })


访问结果坑定是报错,提示的正是无法进行跨域访问



那么问题就是解决跨域问题了  

跨域  要解决这个问题很简单,

只要使页面的前缀和接口的前缀一致就可以了,因此可以使用nginx进行反向代理。打开nginx目录下的conf文件夹,在nginx.conf文件的配置如下:


1.修改nginx.config配置:

#默认监听80端口,ip后面不加端口号默认就是80
        listen       80;
        #服务器地址
        server_name  localhost;
        #charset koi8-r;
        #access_log  logs/host.access.log  main;
        #项目根目录,一般就是启动页
        location / {
            #项目所在目录
            root   C:\Users\shengmengqi\WebstormProjects\angularJsFrame;
            #假设across-domain.html的首页,如果之后页面中跳转也是基于http://localhost/跳转
            index  across-domain.html;
        }
        #作用:访问的http://localhost:80/demo2/相当于一个代理url,实际访问的是http://localhost:8082/demo2/;
        location /demo2/{
            proxy_pass http://localhost:8082/demo2/;
        }

2.修改ajax中的请求url

$(function(){
        $.ajax({
            url: "http://localhost/demo2/login",
            type: "POST",
            contentType: "application/json",
            data: JSON.stringify({
                        "name": "tomcat",
                        password:"oracle"
                    }),
            success: function(data) {
               alert("success")
            },
        })

3.启动nginx.

将ngnix启动起来,在任务管理器中是否有nginx进程,有的话说明启动成功,如果没有,可以查看nginx目录下log文件夹中的error.log,看哪里有问题进行修改,启动成功后,在浏览器地址栏直接访问localhost,这次结果就正确了。 


nginx打印response nginx打印cookie_cookie



ajax的请求请求其实是走了nginx代理服务器的.


nginx打印response nginx打印cookie_nginx_02



是不是感觉有点像tomcat配置虚拟路径的感觉啊

还有一种解决方案(前后端分离):

案例:业务上线以后,前端页面出现了跨域问题,域名1.xxx.com 跨域访问 2.xxx.com/login/的url,浏览器页面产生问题

   在2.xxx.com的nginx配置项中,添加如下请求头

if ($http_origin ~* (http://1\.xxx\.com$)) {
                     add_header Access-Control-Allow-Headers 'Cookie,Set-Cookie,x-requested-with,content-type';
                     add_header Access-Control-Allow-Origin $http_origin ;
                     add_header 'Access-Control-Allow-Credentials' 'true';
                     add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS';
                }



大概解释一下,就是从1.xxx.com域名发的请求,可以跨域到2.sss.xxx/login

   在2.sss.com的nginx配置项中,添加如下请求头



if ($http_origin ~* (http://1\.sss\.com$)) {
                     add_header Access-Control-Allow-Headers 'Cookie,Set-Cookie,x-requested-with,content-type';
                     add_header Access-Control-Allow-Origin $http_origin ;
                     add_header 'Access-Control-Allow-Credentials' 'true';
                     add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS';
                }



大概解释一下,就是从1.sss.com域名发的请求,可以跨域到2.sss.com/bond

进行上面的配置以后,跨域问题解决,浏览器不报错,但是又出现另一个问题,后端tomcat响应头中,一直Set-Cookie,登陆业务一直错误,



确认前端代码,有没有支持跨域请求,需要在js代码中添加一下代码,让前端支持跨域



 



$.ajax({
   url: "xxxxxx",
   // 将XHR对象的withCredentials设为true
   xhrFields:{
      withCredentials:true
   }});

解决方案三(这是大boss的方案:Nginx + Tomcat + HTTPS极速配置)

1.首先去阿里申请免费的https证书

1528815948944.pem; 
1528815948944.key;

nginx打印response nginx打印cookie_html_03


2.修改nginx配置文件 nginx.conf 

#user  nobody;  
worker_processes  1; 
 

  #error_log  logs/error.log; 
 
#error_log  logs/error.log  notice;  
#error_log  logs/error.log  info; 
 

  #pid        logs/nginx.pid; 

 
  
events {  
    worker_connections  1024;  
} 
 
  
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  logs/access.log  main; 

 

      sendfile        on; 
 
    #tcp_nopush     on; 
 

      #keepalive_timeout  0; 
 
    keepalive_timeout  65; 
 

      #gzip  on; 
 
   
 #tomcat集群的入口  
 upstream tomcat {     
  server 127.0.0.1:8180 ;    
    
 } 
 

      server   { 
 
  listen       80 ;  
          listen       443 ssl;  
 # 监听https 请求  
 
          server_name  127.0.0.1; 
 #这里是你的域名,要与下面tomcat里的保持一致 
 
  # ssl 证书配置路径(可花钱买)  
  ssl_certificate      H://apache-tomcat-7.0.82//conf//1528815948944.pem;  
  ssl_certificate_key  H://apache-tomcat-7.0.82//conf//1528815948944.key;  
    
  ssl_session_cache    shared:SSL:1m;   
  ssl_session_timeout  5m;   
    
  ssl_ciphers  HIGH:!aNULL:!MD5;   
  ssl_prefer_server_ciphers  on;  
 

          #charset koi8-r; 

 

          #access_log  logs/host.access.log  main; 

 

         
 
    
  location / {  
     
     #处理浏览器OPTIONS 预请求,默认返回200  
 
     if ($request_method = 'OPTIONS') {
    add_header 'Access-Control-Allow-Credentials' true;
    add_header 'Access-Control-Allow-Origin' "$http_origin";
    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,Content-Range,Range';
    add_header 'Access-Control-Max-Age' 1728000;
    add_header 'Content-Type' 'application/json; charset=utf-8';
    add_header 'Content-Length' 0;
    return 200;
   }  
     
   proxy_pass http://tomcat ;  
   #tomcat支持https 请求,须tomcat 更改相关配置  
   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  
   proxy_set_header Host $http_host;  
   proxy_set_header X-Forwarded-Proto https;  
   proxy_redirect off;    
    
    
        } 
 

          #error_page  404              /404.html; 

 

          # redirect server error pages to the static page /50x.html 
 
        #  
        error_page   500 502 503 504  /50x.html;  
        location = /50x.html {  
            root   html;  
        } 
 

          # proxy the PHP scripts to Apache listening on 127.0.0.1:80 
 
        #  
        #location ~ \.php$ {  
        #    proxy_pass   http://127.0.0.1;  
        #} 
 

          # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 
 
        #  
        #location ~ \.php$ {  
        #    root           html;  
        #    fastcgi_pass   127.0.0.1:9000;  
        #    fastcgi_index  index.php;  
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;  
        #    include        fastcgi_params;  
        #} 
 

          # deny access to .htaccess files, if Apache's document root 
 
        # concurs with nginx's one  
        #  
        #location ~ /\.ht {  
        #    deny  all;  
        #}  
    } 
 
  
    # another virtual host using mix of IP-, name-, and port-based configuration  
    #  
    #server {  
    #    listen       8000;  
    #    listen       somename:8080;  
    #    server_name  somename  alias  another.alias; 
 

      #    location / { 
 
    #        root   html;  
    #        index  index.html index.htm;  
    #    }  
    #} 
 
  
    # HTTPS server  
    #  
    #server {  
    #    listen       443 ssl;  
    #    server_name  localhost; 
 

      #    ssl_certificate      cert.pem; 
 
    #    ssl_certificate_key  cert.key; 
 

      #    ssl_session_cache    shared:SSL:1m; 
 
    #    ssl_session_timeout  5m; 
 

      #    ssl_ciphers  HIGH:!aNULL:!MD5; 
 
    #    ssl_prefer_server_ciphers  on; 
 

      #    location / { 
 
    #        root   html;  
    #        index  index.html index.htm;  
    #    }  
    #} 
 

  }



3.进入tomcat,找到conf文件夹中的server.xml

找到<Connector port="8080" protocol="HTTP/1.1" 这一行,修改为:

1. <Connector port="8080" protocol="HTTP/1.1"  
2. connectionTimeout="20000"  
3. redirectPort="443"  
4. proxyPort="443" />

4.修改HOST里的value值,我这里修改为:

1. <Host name="<span style="color:#FF0000;">www.cjluzzl.cn</span>"  appBase="webapps" <!--这里的name要与nginx配置文件里的server_name保持一致-->  
2. unpackWARs="true" autoDeploy="true">  
3.   
4. <Valve className="org.apache.catalina.valves.RemoteIpValve"  
5. remoteIpHeader="x-forwarded-for"  
6. remoteIpProxiesHeader="x-forwarded-by"  
7. protocolHeader="x-forwarded-proto" />  
8. </Host>

到这里已经实现了前端跨域,要实现后端跨域还需加上以下配置:加个后端允许跨域

nginx打印response nginx打印cookie_nginx打印response_04

<!-- 接口跨域配置 -->  
   <mvc:cors>  
    <mvc:mapping path="/**"  
                      allowed-origins="*"  
                      allowed-methods="POST, GET, OPTIONS, DELETE, PUT"  
                      allowed-headers="Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With"  
                      allow-credentials="true" />  
    </mvc:cors>

可在web.xml中添加,也可通过注解的方式允许跨域,我在这里用mvc.xml方式.可以通过https实现跨域访问啦.