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&mysql(一)
Oct 09 PHP
很实用的一个完整email发送程序
Oct 09 PHP
php中截取字符串支持utf-8
Jan 18 PHP
php 计划任务 检测用户连接状态
Mar 29 PHP
php中的mongodb select常用操作代码示例
Sep 06 PHP
php获取根域名方法汇总
Oct 28 PHP
使用Appcan客户端自动更新PHP版本号(全)
Jul 31 PHP
PHP构造函数与析构函数用法示例
Sep 28 PHP
php实现小程序支付完整版
Oct 09 PHP
laravel清除视图缓存的代码
Oct 23 PHP
php7 错误处理机制修改实例分析
May 25 PHP
PHP中的异常处理机制深入讲解
Nov 10 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模板引擎smarty生成随机数的方法和math函数详解
2014/04/24 PHP
php多个文件及图片上传实例详解
2014/11/10 PHP
培养自己的php编码规范
2015/09/28 PHP
用PHP的socket实现客户端到服务端的通信实例详解
2017/02/04 PHP
不同的jQuery API来处理不同的浏览器事件
2012/12/09 Javascript
treepanel动态加载数据实现代码
2012/12/15 Javascript
javascript dom追加内容实现示例
2013/09/21 Javascript
Javascript 构造函数详解
2014/10/22 Javascript
简单的jQuery入门指引
2015/07/28 Javascript
浅谈JavaScript的Polymer框架中的behaviors对象
2015/07/29 Javascript
jQuery+css3实现文字跟随鼠标的上下抖动
2015/07/31 Javascript
浅析js中substring和substr的方法
2015/11/09 Javascript
微信公众平台开发教程(五)详解自定义菜单
2016/12/02 Javascript
Vue概念及常见命令介绍(1)
2016/12/08 Javascript
node.js Sequelize实现单实例字段或批量自增、自减
2016/12/08 Javascript
js仿京东轮播效果 选项卡套选项卡使用
2017/01/12 Javascript
详解微信小程序调起键盘性能优化
2018/07/24 Javascript
详解vuex commit保存数据技巧
2018/12/25 Javascript
Vue+Node实现的商城用户管理功能示例
2019/12/23 Javascript
跟老齐学Python之使用Python查询更新数据库
2014/11/25 Python
用Python制作在地图上模拟瘟疫扩散的Gif图
2015/03/31 Python
在Python中处理字符串之isdecimal()方法的使用
2015/05/20 Python
Python 正则表达式入门(初级篇)
2016/12/07 Python
TensorFLow用Saver保存和恢复变量
2018/03/10 Python
python框架中flask知识点总结
2018/08/17 Python
简单了解django缓存方式及配置
2019/07/19 Python
13个Pandas实用技巧,助你提高开发效率
2020/08/19 Python
泰国演唱会订票网站:StubHub泰国
2018/02/26 全球购物
医学生个人求职信范文
2013/09/24 职场文书
客户接待方案
2014/02/26 职场文书
班级文化建设标语
2014/06/23 职场文书
班主任与学生安全责任书
2014/07/25 职场文书
2015年教研组工作总结
2015/05/04 职场文书
2015年大学团支部工作总结
2015/05/13 职场文书
2019年最新借条范本!
2019/07/08 职场文书
与Windows10相比Windows11有哪些改进?值不值得升级?
2021/11/21 数码科技