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 保留字列表
Oct 04 PHP
PHP中设置一个严格30分钟过期Session面试题的4种答案
Jul 30 PHP
php实现webservice实例
Nov 06 PHP
codeigniter发送邮件并打印调试信息的方法
Mar 21 PHP
PHP安装memcached扩展笔记
May 28 PHP
PHP中SSO Cookie登录分析和实现
Nov 06 PHP
php获取网站根目录物理路径的几种方法(推荐)
Mar 04 PHP
PHP使用pdo实现事务处理操作示例
Sep 05 PHP
php基于Redis消息队列实现的消息推送的方法
Nov 28 PHP
不常用但很实用的PHP预定义变量分析
Jun 25 PHP
PHP大文件切割上传功能实例分析
Jul 01 PHP
php的单例模式及应用场景详解
Feb 27 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中抽象类和接口的概念以及区别
2013/06/27 PHP
php的debug相关函数用法示例
2016/07/11 PHP
PHP单例模式详解及实例代码
2016/12/21 PHP
基于CI(CodeIgniter)框架实现购物车功能的方法
2018/04/09 PHP
PHP反射实际应用示例
2019/04/03 PHP
jQuery asp.net 用json格式返回自定义对象
2010/04/07 Javascript
jQuery EasyUI API 中文文档 - Dialog对话框
2011/11/15 Javascript
js操作label给label赋值及取label的值示例
2013/11/07 Javascript
Angular用来控制元素的展示与否的原生指令介绍
2015/01/07 Javascript
javascript实现仿腾讯游戏选择
2015/05/14 Javascript
javascript实现的闭包简单实例
2015/07/17 Javascript
利用Javascript实现BMI计算器
2016/08/16 Javascript
基于Bootstrap 3 JQuery及RegExp的表单验证功能
2017/02/16 Javascript
JS实现快速比较两个字符串中包含有相同数字的方法
2017/09/11 Javascript
详解基于vue的服务端渲染框架NUXT
2018/06/20 Javascript
React router动态加载组件之适配器模式的应用详解
2018/09/12 Javascript
每个 JavaScript 工程师都应懂的33个概念
2018/10/22 Javascript
vue 解决遍历对象显示的顺序不对问题
2019/11/07 Javascript
vue 查看dist文件里的结构(多种方式)
2020/01/17 Javascript
解决vue init webpack 下载依赖卡住不动的问题
2020/11/09 Javascript
Django小白教程之Django用户注册与登录
2016/04/22 Python
Python中import导入上一级目录模块及循环import问题的解决
2016/06/04 Python
python 利用栈和队列模拟递归的过程
2018/05/29 Python
浅谈pytorch grad_fn以及权重梯度不更新的问题
2019/08/20 Python
TensorFlow通过文件名/文件夹名获取标签,并加入队列的实现
2020/02/17 Python
Python栈的实现方法示例【列表、单链表】
2020/02/22 Python
Pandas时间序列基础详解(转换,索引,切片)
2020/02/26 Python
keras-siamese用自己的数据集实现详解
2020/06/10 Python
h5实现获取用户地理定位的实例代码
2017/07/17 HTML / CSS
英国团购网站:Groupon英国
2017/11/28 全球购物
欧尚俄罗斯网上超市:Auchan俄罗斯
2018/05/03 全球购物
公司经理任命书
2014/06/05 职场文书
酒店财务部岗位职责
2015/04/14 职场文书
《七月的天山》教学反思
2016/02/19 职场文书
高中生物教学反思
2016/02/20 职场文书
Springboot-cli 开发脚手架,权限认证,附demo演示
2022/04/28 Java/Android