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之数据库操作详解及乱码解决!
Jan 02 PHP
php面向对象全攻略 (十四) php5接口技术
Sep 30 PHP
CodeIgniter安全相关设置汇总
Jul 03 PHP
php跨站攻击实例分析
Oct 28 PHP
thinkphp模板用法和内容输出实例
Nov 28 PHP
php给一组指定关键词添加span标签的方法
Mar 31 PHP
PHP实现无限级分类(不使用递归)
Oct 22 PHP
PHP中Restful api 错误提示返回值实现思路
Apr 12 PHP
利用php-cli和任务计划实现订单同步功能的方法
May 03 PHP
php中上传文件的的解决方案
Sep 25 PHP
ThinkPHP框架下微信支付功能总结踩坑笔记
Apr 10 PHP
浅谈laravel框架与thinkPHP框架的区别
Oct 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
星际流派综述
2020/03/04 星际争霸
PHP Smarty生成EXCEL文档的代码
2008/08/23 PHP
php各种编码集详解和以及在什么情况下进行使用
2011/09/11 PHP
浅析PHP绘图技术
2013/07/03 PHP
PHP利用APC模块实现文件上传进度条的方法
2015/01/26 PHP
php对接java现实加签验签的实例
2016/11/25 PHP
Thinkphp5框架使用validate实现验证功能的方法
2019/08/27 PHP
css值转换成数值请抛弃parseInt
2011/10/24 Javascript
解析ScrollPic在ie8下只滚动一遍,然后变为空白 ie6,ie7,chrome,firefox正常
2013/06/26 Javascript
详细解读AngularJS中的表单验证编程
2015/06/19 Javascript
js限制input标签中只能输入中文
2015/06/26 Javascript
JavaScript编写简单的计算器
2015/11/25 Javascript
浅析JavaScript中的变量复制、参数传递和作用域链
2016/01/13 Javascript
js CSS3实现卡牌旋转切换效果
2017/07/04 Javascript
Angular2使用SVG自定义图表(条形图、折线图)组件示例
2019/05/10 Javascript
使vue实现jQuery调用的两种方法
2019/05/12 jQuery
用Python编写一个简单的FUSE文件系统的教程
2015/04/02 Python
python中迭代器(iterator)用法实例分析
2015/04/29 Python
Python金融数据可视化汇总
2017/11/17 Python
Python使用Windows API创建窗口示例【基于win32gui模块】
2018/05/09 Python
python list格式数据excel导出方法
2018/10/31 Python
Numpy数组array和矩阵matrix转换方法
2019/08/05 Python
深入了解python中元类的相关知识
2019/08/29 Python
opencv调整图像亮度对比度的示例代码
2019/09/27 Python
python与c语言的语法有哪些不一样的
2020/09/13 Python
前端面试必备之html5的新特性
2017/09/05 HTML / CSS
详解px单位html5响应式方案
2018/03/08 HTML / CSS
详解三种方式实现平滑滚动页面到顶部的功能
2019/04/23 HTML / CSS
娇韵诗加拿大官网:Clarins加拿大
2017/11/20 全球购物
自荐信模版
2013/10/24 职场文书
房地产广告词大全
2014/03/19 职场文书
2014年安全生产大检查方案
2014/05/13 职场文书
培根随笔读书笔记
2015/07/01 职场文书
关于感恩的作文
2019/08/26 职场文书
vue实现Toast组件轻提示
2022/04/10 Vue.js
Python数据可视化之Seaborn的安装及使用
2022/04/19 Python