1 问题场景

最近在学用Python进行web开发,写了一个博客系统,基本的配置如下:

  • 开发语言: Python + javascript
  • 开发框架: Web.py
  • 服务器: virtualbox + centos6.3 + nginx + fastcgi

在本机测试时,完全没有问题,可是部署到服务器上后,发现用户登录后,服务器端设置了cookie, 但是后面需要读 这个cookie时,却读取不到。 这里的读写cookie使用的是Web.py中提供的:

// 设置cookie
web.setcookie ('username', 'tom') // 读取cookie
web.cookies.get('username')

2 解决过程

解决问题真的需要好的思路,就像在设计一个实验,不断地猜测,实验验证,最后得出结论,特别是这种问题你根本 就Google不到,并且你根本不知道到底是哪里出了问题,是客户端,还是服务器,是你写的程序本身出错了,还是框架 本身的代码有问题。

2.1 cookie是否设置成功

对于这个问题, 我们首先要判断cookie是没有设置成功,还是设置成功了,但是客户端没有传上来。 这一点可以通过用户登录后,在客户端查看cookie的方式来验证,我使用的是chrome,可以使用setting->advanced settings ->Privacy->Content setting->All cookies and site data来查看,通过搜索可以看到指定站点的cookie.在这里可以 看到cookie确实设置成功了。

2.2 cookie是否上传到服务器

既然cookie已经在客户端出现,到底是客户端上传到服务器了,服务器没有接收到,还是客户端就没有给服务器上传cookie呢。 这一步可以使用chrome的调试工具,通过查看请求的header确定。具体方法是右击打开Inspect Element, 选择Network,然后 刷新页面,向服务器发请求,这时候,Network部分就会出现这次请求的相关信息,点击左栏出现的项,就可以看到Headers信息, 包括 Request Headers 和 Response Headers, 这里可以发现 Request Headers中没有包含cookie项。

这就很奇怪,客户端有cookie,为什么向服务器发请求时没有携带这个cookie呢?既然客户端的处理不正确,那么为什么在本 机测试时没有问题,部署到服务器后却有了问题呢?为了确定两种方式的不同,我又做对比实验,仔细观察了这两种方式 在客户端设置的cookie, 发现本机测试时cookie的路径是根路径 "/", 而部署到服务器后,cookie的路径却是 "/wpusers/tom/", 注意两次请求的路径一样,都是"192.168.xxx.xxx:/wpusers/tom", 我意识到问题可能 出现在这里,然后就再做实验,在setcookie时,指定路径为 "/", 这一次工作就正常了。看来真的是路径问题。

问题本身已经解决了,但是我们要问,为什么cookie的路径是 "/wpusers/tom/" 就不行呢,总不能所有cookie路径 都是根路径吧。根据以前的经验,有没有 "/",结果是完全不同的,我试探性地将 "/wpusers/tom//" 改成了 "/wpusers/tom", 发现这次居然可以了。原来浏览器访问"192.168.xxx.xxx:/wpusers/tom" 时会携带路径为 "/wpusers/tom" 的cookie, 而不携带 "/wpusers/tom/", 历史再次证明了,有没有"/", 差别是很大的。因为这个问题,我还发现了 另一个问题,就是不同浏览器对此的处理是不同的。我重复了很多次实验,发现chrome和opera的处理方式如上述所示,对有 没有"/"区别很大,而firefox不同,在访问"192.168.xxx.xxx:/wpusers/tom"时,路径是"/wpusers/tom/"的cookie也会 被一起上传。

下面的两张图分别是chrom 和firefox第一次发起请求时的headers, 注意看两者Response headers部分的Set cookie, 这是第一次请求时

服务器给浏览器发来的cookie, path字段都是"/wpusers/tom/"

图1 chrome 第1次请求

图2 firefox 第一次请求

下面我们看第二次请求,这一次注意看两者的request headers部分有没有携带cookie, chrome没有,而firefox 有。(另外,为了实验的方便服务器端setcookie是在请求/wpusers/tom时发生的,所以在response段每次都可以看到Set-cookie字段,但是这不重要,重要的是浏览器在第二次发起请求时,request headers部分是否有cookie字段)

图3 chrome 第二次请求

图4 firefox 第二次请求

还有一个问题,就是最一开始调用setcookie时,我并没有使用path这个参数,路径是被自动设置为"/wpusers/tom/"的, 最后的"/"就是罪魁祸首,为什么会自动设置成这样呢, 我查看了Web.py在Github上的源代码。

webpy/web/webapi.py 中,在setcookie函数中是这样设置路径的。

morsel['path'] = path or ctx.homepath+'/'

意思就是说如果有path路径,我们按path来,没有path路径我们就设置成 ctx.homepath+'/', 问题就出现在这个 ctx.homepath+'/'上,本意是ctx.homepath为空时,设置成根路径,这应该就是本机测试时的情况。而如果访问的是 "/wpusers/tom", 路径就被设置成了 "/wpusers/tom/", 这就会让chrome和opera在读取cookie时出错。问题的 最终原因终于找到,开源软件就是好呀,就是好来就是好~

3 总结

表面原因是cookie的路径设置出的问题

根本原因在于源代码中对path的路径处理出了问题


 

Cookie 路径在本机测试及服务器部署,在浏览器处理方式上的不同的更多相关文章

  1. Android真机测试,连接到本地服务器的方法

    1. 前言 作为一名Android开发者,不管怎么说,都会经历使用Android真机来测试连接本地服务器这样的事情.这里所说的“本地服务器”大多数时候指的是:搭载有某种服务器软件的PC,例如搭载有To ...

  2. cookie的路径决定服务器在发送请求时候 是否决定发送 当路径匹配时候 则发送给服务器(默认发送原则)

    1.cookie路径默认为当前访问地址的上一级路径 2.当前访问地址的路径包含了cookie的路径 则发送给访问的地址 3.路径决定cookie发送与否 4.发送包含在当前路径里面的cookie

  3. 在本地(自己电脑上)部署了tomcat服务器,真机测试遇到的问题

    开始的时候自己就是给app搭建了一个小的框架,只有一个界面发送了网络请求,部署的tomcat,数据成功请求,得到了数据. 后来随着联网请求的增多,突然发现联网请求一直失败.自己dubug了最开始的第一 ...

  4. Windows 8(64位)如何搭建 Android 开发环境与真机测试(转)

    可以参考http://wenku.baidu.com/link?url=ghU6IFS1WJXLFKfM_0efv9YQEnMDBrdi9CXwirSs5IOLLeUfdIOh8OOVv0DX89Lt ...

  5. JMeter压力测试及服务器状态监控教程

    转载自:https://blog.csdn.net/cbzcbzcbzcbz/article/details/78023327 前段时间公司需要对服务器进行压力测试,包括登录前的页面和登录后的页面,主 ...

  6. python web开发c6——阿里云上ubuntu+flask+gunicorn+nginx服务器部署(一)简单测试

    简述 Nginx在服务器部署中的作用 请求通过Nginx实现反向代理,将请求提交给代理服务器.本文中只用了一台服务器,所以是代理到本机. gunicorn的作用 作为服务器代码的容器.接收Nginx的 ...

  7. iOS系列 基础篇 01 构建HelloWorld,剖析并真机测试

    iOS基础 01 构建HelloWorld,剖析并真机测试 前言: 从控制台输出HelloWorld是我们学习各种语言的第一步,也是我们人生中非常重要的一步. 多年之后,我希望我们仍能怀有学习上进的心 ...

  8. Xcode真机测试could not find developer disk image解决方法

    原文地址:http://my.oschina.net/u/2340880/blog/521700 Xcode真机测试could not find developer disk image解决方法 在使 ...

  9. 移动web开发之移动端真机测试

    × 目录 [1]特性 [2]安装 [3]设置[4]移动端 前面的话 chrome的开发者工具可以很好地做好模拟工作,但毕竟模拟和实际还是有差别的.所以,真机测试是一定要做的,如何高效地进行真机测试呢. ...

随机推荐

  1. 关于 IE firefox Chrome下的通过用js 关闭窗口的一些问题

    首先IE是可以通过window.close()来关闭浏览器窗口的,但是在firefox和Chrome下是无效的,原因在于: ~~~ie可直接<button onclick="windo ...

  2. 基于QtQuick2.0应用程序运行于XP系统的诸多问题

    客户端 使用QtQuick技术开发酷炫的XP客户端经常遇到白屏或者无界面 if Qt is built using ANGLE, its shared libraries and the requir ...

  3. jqGrid一些操作

    formatter:function(cellvalue,options,rowObject){} 在格式化行的时候这三个参数 cellvalue行数, options配置信息, rowObject行 ...

  4. 强大的Mockito测试框架(转)

    1.自动生成Mock类在需要Mock的属性上标记@Mock注解,然后@RunWith中配置Mockito的TestRunner或者在setUp()方法中显示调用MockitoAnnotations.i ...

  5. commons-logging和slf4j都是日志的接口

    过上面的图,可以简单的理清关系! commons-logging和slf4j都是日志的接口,供用户使用,而没有提供实现! log4j,logback等等才是日志的真正实现. 当我们调用接口时,接口的工 ...

  6. c++ 对象作为参数传递

    对象作为参数传递时是传值.把实参的对象赋值给形参.因此效率有点低. c++传参方式可以分为2种: 1.传值 (指针作为参数,本质上也只是把地址作为值传递了而已). 2.传引用. 所以,一切传递方式不是 ...

  7. Android基调(十六)- Service:startService()、stopService()、bindService()、unbindService()加

    直行 第一 另外一种 第三种 总结 开门见山 开启服务有三种情况:假设直接使用服务,则没有必要进行绑定,可是假设要使用服务里面的方法.则要进行绑定. 具体的启动情况有下: ①调用startServic ...

  8. Unity Notes调制粒子系统的颗粒的最大数目

    Unity该粒子系统是很容易使用.这样的问题是在实际的过程中遇到的:以控制的粒子系统组件的动态需要可产生颗粒的最大数目. 看doc他说,有maxParticles控制.却没有这个开放的參数.仅仅能通过 ...

  9. hdu4597 Play Game(DFS)

    转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=4597 题意 Alic ...

  10. ADS2008 安装方法详解及文件下载

    一.我的安装的过程及方法 正常安装的方法: 1.- Install the program. 2.- Copy "license.lic" into "C:\ADS200 ...