Cookie跨域问题解决方案代码示例


Posted in PHP onNovember 24, 2020

一、前言

随着项目模块越来越多,很多模块现在都是独立部署。模块之间的交流有时可能会通过cookie来完成。比如说门户和应用,分别部署在不同的机器或者web容器中,假如用户登陆之后会在浏览器客户端写入cookie(记录着用户上下文信息),应用想要获取门户下的cookie,这就产生了cookie跨域的问题。

二、介绍一下cookiev  

cookie路径:

cookie 一般都是由于用户访问页面而被创建的,可是并不是只有在创建 cookie 的页面才可以访问这个cookie。在默认情况下,出于安全方面的考虑,只有与创建 cookie 的页面处于同一个目录或在创建cookie页面的子目录下的网页才可以访问。那么此时如果希望其父级或者整个网页都能够使用cookie,就需要进行路径的设置。

path表示cookie所在的目录,asp.net默认为/,就是根目录。在同一个服务器上有目录如下:/test/,/test/cd/,/test/dd/,现设一个cookie1的path为/test/,cookie2的path为/test/cd/,那么test下的所有页面都可以访问到cookie1,而/test/和/test/dd/的子页面不能访问cookie2。这是因为cookie能让其path路径下的页面访问。

让这个设置的cookie 能被其他目录或者父级的目录访问的方法:

document.cookie = "name = value; path=/";

 cookie 域:

domain表示的是cookie所在的域,默认为请求的地址,如网址为3water.com/test/test.aspx,那么domain默认为3water.com。而跨域访问,如域A为t1.test.com,域B为t2.test.com,那么在域A生产一个令域A和域B都能访问的cookie就要将该cookie的domain设置为.test.com;如果要在域A生产一个令域A不能访问而域B能访问的cookie就要将该cookie的domain设置为t2.test.com。

三、解决cookie跨域问题之nginx反向代理

 反向代理概念

反向代理(Reverse Proxy)方式是指以代理服务器来接受Internet上的连接请求,然后将请求转发给内部网络上的服务器;并将从服务器上得到的结果返回给Internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器。

反向代理服务器对于客户端而言它就像是原始服务器,并且客户端不需要进行任何特别的设置。客户端向反向代理 的命名空间(name-space)中的内容发送普通请求,接着反向代理将判断向何处(原始服务器)转交请求,并将获得的内容返回给客户端,就像这些内容 原本就是它自己的一样。

场景模拟

两个工程web1,web2,部署在同一台机器上的不同tomcat上,请求web1工程的index.html,如下:

Cookie跨域问题解决方案代码示例

然后点击链接请求web2工程的index.jsp,内容如下:

Cookie跨域问题解决方案代码示例

再看一下nginx的配置,如下:

worker_processes 2; 
events {
  worker_connections 65535;
}
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"';
  server_names_hash_bucket_size 128;
  client_header_buffer_size 32k;
  large_client_header_buffers 4 32k;
  client_body_buffer_size  8m;
  server_tokens off;
  ignore_invalid_headers  on;
  recursive_error_pages  on;
  server_name_in_redirect off;
  sendfile    on;
  tcp_nopush   on;
  tcp_nodelay  on;
  #keepalive_timeout 0;
  keepalive_timeout 65;
  upstream web1{
     server 127.0.0.1:8089 max_fails=0 weight=1;
  }
  upstream web2 {
     server 127.0.0.1:8080  max_fails=0 weight=1;
  }
  
  server {
    listen    80;
    server_name 127.0.0.1;
    charset utf-8;
    index index.html;
   
    location /web/web1 {
      proxy_pass http://web1/web1;
      proxy_set_header Host 127.0.0.1;
      proxy_set_header  X-Real-IP    $remote_addr;
      proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
 
      proxy_set_header Cookie $http_cookie;
      log_subrequest on;
    }
 
    location /web/web2 {
      proxy_pass http://web2/web2;
      proxy_set_header Host 127.0.0.1;
      proxy_set_header  X-Real-IP    $remote_addr;
      proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Cookie $http_cookie;
      log_subrequest on;
    }
 
    location /nginxstatus {
      stub_status on;
      access_log on;
    }
    error_page  500 502 503 504 /50x.html;
    location = /50x.html {
      root  html;
    }
  }
}

这样就可以保证cookie在同一域下。web2工程中的index.jsp中的输出内容如下:

Cookie跨域问题解决方案代码示例v

总结

利用nginx的方向代理来解决cookie跨域问题,其实是通过“欺骗”浏览器来实现的,通过nginx,我们可以将不同工程的cookie放到nginx域下,通过nginx反向代理就可以取到不同工程写入的cookie。其实上述场景中$.cookie("user", "hjzgg", {path: "/web"}); 中的path可以写成 “/”, 这样nginx的配置就更为简单了,如下。

location /web1 {
      proxy_pass http://web1;
      proxy_set_header Host 127.0.0.1;
      proxy_set_header  X-Real-IP    $remote_addr;
      proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
 
      proxy_set_header Cookie $http_cookie;
      log_subrequest on;
    }
 
    location /web2 {
      proxy_pass http://web2;
      proxy_set_header Host 127.0.0.1;
      proxy_set_header  X-Real-IP    $remote_addr;
      proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Cookie $http_cookie;
      log_subrequest on;
    }

四、解决cookie跨域问题之jsonp方式请求

 jquery请求跨域:

JQuery对于Ajax的跨域请求有两类解决方案,不过都是只支持get方式。分别是JQuery的jquery.ajaxjsonp格式和jquery.getScript方式。

 jsonp格式:

如果获取的数据文件存放在远程服务器上(域名不同,也就是跨域获取数据),则需要使用jsonp类型。使用这种类型的话,会创建一个查询字符串参数 callback=? ,这个参数会加在请求的URL后面。服务器端应当在JSON数据前加上回调函数名,以便完成一个有效的JSONP请求。意思就是远程服务端需要对返回的数据做下处理,根据客户端提交的callback的参数,返回一个callback(json)的数据,而客户端将会用script的方式处理返回数据,来对json数据做处理。JQuery.getJSON也同样支持jsonp的数据方式调用。

场景模拟:

两个工程web1,web2,部署在本地同一台机器上的不同tomcat上,端口分别是8080和8089。

web2/index.html内容如下:

Cookie跨域问题解决方案代码示例

  web2/cooke.jsp内容如下:

Cookie跨域问题解决方案代码示例

web1/index.html内容如下:

Cookie跨域问题解决方案代码示例

测试流程,首先通过谷歌浏览器访问http://localhost:8089/web2/index.html,F12,Network视图,查看内容如下:

 Cookie跨域问题解决方案代码示例

或者通过浏览器设置->显示高级设置->隐私设置来查看写入的cookie,过程如下。

Cookie跨域问题解决方案代码示例

 接着,打开另一个窗口,访问http://localhost:8080/web1/index.html,这个页面是请求web2工程写入的cookie(注意,如果我们不是通过jsonp方式去访问,那么浏览器就会出现 不允许跨域访问 的提示)。同样 F12, Network视图,查看返回的数据如下。

Cookie跨域问题解决方案代码示例

Cookie跨域问题解决方案代码示例 Cookie跨域问题解决方案代码示例Cookie跨域问题解决方案代码示例

至此,通过jsonp方式的请求完成cookie跨域携带,也就是web1工程成功拿到了web2工程目录下的cookie。可以发现,jsonp会通过回调函数来处理服务器端返回的数据,因为返回的可以执行的js代码(也就是重写cookie的path和域),然后自动执行返回的js代码,从而达到目的。

五、解决cookie跨域问题之nodejs superagent

package.json中的模块依赖:

Cookie跨域问题解决方案代码示例

调用superagent api请求: 

Cookie跨域问题解决方案代码示例

六、同一域下,不同工程下的cookie携带问题

cookie跨域访问之后,可以成功的写入本地域。本地的前端工程在请求后端工程时,有很多是ajax请求,ajax默认不支持携带cookie,所以现在有以下两种方案:

(1). 使用jsonp格式发送

(2). ajax请求中加上字段xhrFields:{withCredentials:true},这样可以携带上cookie

Cookie跨域问题解决方案代码示例

 这样后台配置就出现了限制,需要配置一个解决跨域访问的过滤器,而且header字段Access-Control-Allow-Origin的值不能为"*", 必须是一个确定的域。

Cookie跨域问题解决方案代码示例

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
php chr() ord()中文截取乱码问题解决方法
Sep 08 PHP
发款php蜘蛛统计插件只要有mysql就可用
Oct 12 PHP
ThinkPHP调用common/common.php函数提示错误function undefined的解决方法
Aug 25 PHP
自定义session存储机制避免会话保持问题
Oct 08 PHP
smarty模板引擎之配置文件数据和保留数据
Mar 30 PHP
浅析PHP关键词替换的类(避免重复替换,保留与还原原始链接)
Sep 22 PHP
php验证邮箱和ip地址最简单方法汇总
Oct 30 PHP
Yii快速入门经典教程
Dec 28 PHP
header与缓冲区之间的深层次分析
Jul 30 PHP
php遍历、读取文件夹中图片并分页显示图片的方法
Nov 15 PHP
PHP操作Redis常用技巧总结
Apr 24 PHP
PHP的mysqli_set_charset()函数讲解
Jan 23 PHP
PHP执行linux命令6个函数代码实例
Nov 24 #PHP
PHP获取真实IP及IP模拟方法解析
Nov 24 #PHP
Thinkphp极验滑动验证码实现步骤解析
Nov 24 #PHP
ThinkPhP+Apache+PHPstorm整合框架流程图解
Nov 23 #PHP
phpstorm最新激活码分享亲测phpstorm2020.2.3版可用
Nov 22 #PHP
php操作redis命令及代码实例大全
Nov 19 #PHP
PHP实现倒计时功能
Nov 16 #PHP
You might like
PHP 之Section与Cookie使用总结
2012/09/14 PHP
解析PHP强制转换类型及远程管理插件的安全隐患
2014/06/30 PHP
PHP编程获取各个时间段具体时间的方法
2017/05/26 PHP
JS 自定义函数缺省值的设置方法
2010/05/05 Javascript
使用js操作cookie的一点小收获分享
2013/09/03 Javascript
jquery获取颜色在ie和ff下的区别示例介绍
2014/03/28 Javascript
node.js实现多图片上传实例
2014/06/03 Javascript
基于编写jQuery的无缝滚动插件
2014/08/02 Javascript
Javascript学习笔记之数组的构造函数
2014/11/23 Javascript
JavaScript设计模式之代理模式介绍
2014/12/28 Javascript
Jquery实现遮罩层的方法
2015/06/08 Javascript
JS弹出新窗口被拦截的解决方法
2016/08/09 Javascript
jquery插件bootstrapValidator数据验证详解
2016/11/09 Javascript
JavaScript函数节流和函数防抖之间的区别
2017/02/15 Javascript
关于HTTP传输中gzip压缩的秘密探索分析
2018/01/12 Javascript
vue组件实现弹出框点击显示隐藏效果
2020/10/26 Javascript
jQuery实现的监听导航滚动置顶状态功能示例
2018/07/23 jQuery
vue 使用vant插件做tabs切换和无限加载功能的实现
2020/11/04 Javascript
python encode和decode的妙用
2009/09/02 Python
Python 爬虫的工具列表大全
2016/01/31 Python
python爬虫之urllib库常用方法用法总结大全
2018/11/14 Python
如何在Django配置文件里配置session链接
2019/08/06 Python
TFRecord格式存储数据与队列读取实例
2020/01/21 Python
python使用docx模块读写docx文件的方法与docx模块常用方法详解
2020/02/17 Python
在Python中通过threshold创建mask方式
2020/02/19 Python
Python更换pip源方法过程解析
2020/05/19 Python
HTML5本地存储之Web Storage详解
2016/07/04 HTML / CSS
《自选商场》教学反思
2014/02/14 职场文书
赔偿协议书范本
2014/04/15 职场文书
大专学生求职信
2014/07/04 职场文书
2014幼儿园小班工作总结
2014/11/10 职场文书
机关保密工作承诺书
2015/05/04 职场文书
圆明园纪录片观后感
2015/06/03 职场文书
关于观后感的作文
2015/06/18 职场文书
运动会加油稿50字
2015/07/21 职场文书
SpringDataJPA在Entity中常用的注解介绍
2021/12/06 Java/Android