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 相关文章推荐
PHP4中实现动态代理
Oct 09 PHP
用户的详细注册和判断
Oct 09 PHP
PHP 远程文件管理,可以给表格排序,遍历目录,时间排序
Aug 07 PHP
php 文件上传代码(限制jpg文件)
Jan 05 PHP
php做下载文件的实现代码及文件名中乱码解决方法
Feb 03 PHP
eAccelerator的安装与使用详解
Jun 13 PHP
解决PHP4.0 和 PHP5.0类构造函数的兼容问题
Aug 01 PHP
PHP命令行脚本接收传入参数的三种方式
Aug 20 PHP
php使用GD库创建图片缩略图的方法
Jun 10 PHP
PHP封装的HttpClient类用法实例
Jun 17 PHP
在 Laravel 中 “规范” 的开发短信验证码发送功能
Oct 26 PHP
PHP底层运行机制与工作原理详解
Jul 31 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获取网络文件的实现代码
2010/01/01 PHP
PHP实现对站点内容外部链接的过滤方法
2014/09/10 PHP
smarty模板引擎从配置文件中获取数据的方法
2015/01/22 PHP
php实现点击可刷新验证码
2015/11/07 PHP
PHP MVC框架skymvc支持多文件上传
2016/05/26 PHP
PHP入门教程之表单与验证实例详解
2016/09/11 PHP
PHP数据库处理封装类实例
2016/12/24 PHP
Kindeditor编辑器添加图片上传水印功能(php代码)
2017/08/03 PHP
JS 中document.URL 和 windows.location.href 的区别
2009/11/11 Javascript
JS 有趣的eval优化输入验证实例代码
2013/09/22 Javascript
js实现键盘操作实现div的移动或改变的原理及代码
2014/06/23 Javascript
Jquery时间轴特效(三种不同类型)
2015/11/02 Javascript
javascript的正则匹配方法学习
2016/02/24 Javascript
JS获取复选框的值,并传递到后台的实现方法
2016/05/30 Javascript
Node.js websocket使用socket.io库实现实时聊天室
2017/02/20 Javascript
IntelliJ IDEA 安装vue开发插件的方法
2017/11/21 Javascript
ssm+vue前后端分离框架整合实现(附源码)
2020/07/08 Javascript
跟老齐学Python之Python安装
2014/09/12 Python
跟老齐学Python之有点简约的元组
2014/09/24 Python
Centos5.x下升级python到python2.7版本教程
2015/02/14 Python
Python中内置的日志模块logging用法详解
2016/07/12 Python
实践Vim配置python开发环境
2018/07/02 Python
Python将一个Excel拆分为多个Excel
2018/11/07 Python
pandas通过索引进行排序的示例
2018/11/16 Python
详解HTML5中的Communication API基本使用方法
2016/01/29 HTML / CSS
法国大使拉杆箱官网:DELSEY Paris
2018/03/20 全球购物
日本快乐生活方式购物网站:Shop Japan
2018/07/17 全球购物
史上最全面的Java面试题汇总!
2015/02/03 面试题
简历中个人自我评价范文
2013/12/26 职场文书
大学优秀班集体申报材料
2014/05/23 职场文书
2014年学习厉行节约反对浪费思想汇报
2014/09/10 职场文书
关于晚自习早退的检讨书
2014/09/13 职场文书
如何写好活动总结
2019/06/21 职场文书
2019员工保密协议书(3篇)
2019/09/23 职场文书
pytorch 如何使用amp进行混合精度训练
2021/05/24 Python
Hive日期格式转换方法总结
2022/06/25 数据库