简体   繁体   English

为什么在兼容打开的页面之间共享PHP会话似乎在FF中有效,而不是IE或Chrome?

[英]Why does sharing PHP sessions between concurrently open pages seem to work in FF, but not IE or Chrome?

EDIT I just realized that I must have had a massive brain fart while writing the abbreviated code sample. 编辑我刚刚意识到在编写缩写代码示例时我必须有一个大脑屁。 See, I'm using smarty. 看,我用得很聪明。 Thus, I'm actually already using Kips's solution, because smarty displays after the session is saved 因此,我实际上已经在使用Kips的解决方案了,因为会话保存后会有智能显示

I've been working on implementing a resource manager (for condensing, compressing and minifying CSS & JS) for a PHP site I'm working on and have run into an awfully strange problem. 我一直在为我正在研究的PHP站点实现一个资源管理器(用于压缩,压缩和缩小CSS和JS),并且遇到了一个非常奇怪的问题。 So when a user navigates to index.php, files are added to a resource manager object, which combines them into a single file and are included in the page via either <script src="resource.php?id=123&ext=.js"> or <link href="resource.php?id=123&ext=.css" /> 因此,当用户导航到index.php时,文件被添加到资源管理器对象,该对象将它们组合成单个文件,并通过<script src="resource.php?id=123&ext=.js">包含在页面中。 <script src="resource.php?id=123&ext=.js"><link href="resource.php?id=123&ext=.css" />

What it basically boils down to is that a file path is stored in a session on the accessed page and read from the session on the resource page. 它基本上归结为文件路径存储在被访问页面上的会话中,并从资源页面上的会话中读取。 In FF, this works perfectly fine. 在FF中,这完全正常。 In IE and Chrome, it does not. 在IE和Chrome中,它没有。

Here's a much-abbreviated code sample: 这是一个非常简短的代码示例:

index.php 的index.php

<?php
session_start();
//Do a ton of stuff
//Including adding several files to the resource object
//Add the resource links to the head
$smarty->append('headSection','<link href="resource.php?id=<?=$resourceID?>&type=.js" />');
</head>
//Save the resource file which:
// - Outputs the file
// - Saves a reference to it in session
$_SESSION[$resourceID] = $file;
//Let Smarty display
$smarty->display($templateFile);
?>

resource.php resource.php

<?php
readfile($_SESSION[$_GET['id']] . $_GET['type']);
?>

What it seems like to me is that FF waits for an entire page response before making any new requests to the resources required by the page, while IE and Chrome function by starting a new request the second it is encountered. 对我来说似乎是FF在对页面所需的资源提出任何新请求之前等待整个页面响应,而IE和Chrome通过在遇到第二个请求时启动新请求来运行。 Due to this, this error basically boils down to a race condition. 因此,这个错误基本上归结为竞争条件。

Can anyone confirm that this is indeed the way it works? 任何人都可以确认这确实是它的工作方式吗? And if so - how would I work around it? 如果是这样 - 我将如何解决它?

Edit : After the update to your question, then I am not surprised that you are getting a race condition. 编辑 :在更新您的问题之后,我对您遇到竞争条件并不感到惊讶。 I don't know why it is working in Firefox, but IE and Chrome are certainly not doing anything illegal by requesting the resources early. 我不知道为什么它在Firefox中运行,但IE和Chrome肯定没有通过提前请求资源做任何违法行为。 One way you could resolve this is with output buffering. 解决这个问题的一种方法是使用输出缓冲。 At the top of your index.php file, you can add: 在index.php文件的顶部,您可以添加:

ob_start('ob_gzhandler');

This kills two birds with one stone, by: a) making sure that output is buffered, so the browser doesn't see the file until the whole page has been generated; 这可以通过以下方式杀死两只鸟:a)确保输出被缓冲,因此浏览器在生成整个页面之前不会看到该文件; and b) saving you and your users bandwidth by using gzip compression. b)使用gzip压缩保存您和您的用户带宽。


Previous answer : That doesn't seem to make sense. 上一个答案 :这似乎没有意义。 Cookies can only be set in the header, which happens before any page content is loaded. Cookie只能在标题中设置,这在加载任何页面内容之前都会发生。 So the browser requests index.php, and the PHPSESSID cookie is set in the header. 因此浏览器请求index.php,并在标头中设置PHPSESSID cookie。 Then the page content is delivered. 然后传递页面内容。

I don't have access to a machine with PHP at the moment, but the following might help to test your theory. 我目前无法使用PHP访问计算机,但以下内容可能有助于测试您的理论。 test1.php sets a session variable, but then takes 30 seconds to completely finish loading. test1.php设置会话变量,但是需要30秒才能完全加载。 Meanwhile, test2.php (a CSS file) will try to use that session variable as the text color. 同时, test2.php (一个CSS文件)将尝试使用该会话变量作为文本颜色。 The text will show up red if the session could be read from test2, or black (default color) otherwise. 如果可以从test2读取会话,则文本将显示为红色;否则,将显示黑色(默认颜色)。

test1.php test1.php

<?php
session_start();
$_SESSION['mycolor'] = 'red';
?>
<html>
<head>
<link rel="stylesheet" href="test2.php" type="text/css" />
</head>
<body>
Starting test...<br/>
<?php
for($i = 0; $i < 6; $i++) //loop will take 30 seconds to complete
{
  echo "$i<br/>\n";
  sleep(5);
}
?>
Done!
</body>
</html>

test2.php test2.php

<?php
session_start();
?>
body { color: <?php echo $_SESSION['mycolor']; ?>; }

I finally figured out what was needed to fix this. 我终于想出了解决这个问题所需要的东西。 For starters, Kip's suggested solution is correct, however it wasn't actually the solution to my problem as what I said was my problem wasn't actually my problem... more or less. 对于初学者来说,Kip建议的解决方案是正确的,但实际上它并不是我问题的解决方案,因为我所说的问题实际上并不是我的问题...或多或少。

In one of the tests I was doing, I noticed suddenly that the SessionID was different for the page and for the resource file. 在我正在进行的其中一个测试中,我突然注意到SessionID对于页面和资源文件是不同的。 I didn't have any idea how that was possible, until I remembered that in another component that I include in the page, I regenerate the SessionID ( session_regenerate_id() ) to prevent CSRF attacks. 我不知道这是怎么可能的,直到我记得在页面中包含的另一个组件中,我重新生成SessionID( session_regenerate_id() )以防止CSRF攻击。 Once I commented out that line, everything worked perfectly in every browser. 一旦我评论出这条线,一切都在每个浏览器中完美运行。

For me however, this raises a new question... Why isn't session_regenerate_id() preserving session data? 然而,对我来说,这提出了一个新问题......为什么session_regenerate_id()不保留会话数据?

Edit - Follow up: It seems that this is actually a known issue and is well documented in the comments on the PHP docs page for session_regenerate_id(). 编辑 - 跟进:似乎这实际上是一个已知问题,并且在sessiondgenerate_id()的PHP文档页面的注释中有详细记录。

Start here: http://www.php.net/manual/en/function.session-regenerate-id.php#81212 and read up. 从这里开始: http//www.php.net/manual/en/function.session-regenerate-id.php#81212并阅读。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在Chrome / FF / IE PHP上强制打开PDF - How to force open PDF on chrome/FF/IE PHP PHP Form无法在IE和Chrome上正常运行,但在FF中可以正常使用 - PHP Form not working IE and Chrome, but fine in FF PHP SQL UPDATE在FF和CHROME中有效,但在IE中不起作用? - PHP SQL UPDATE works in FF and CHROME but not in IE? PHP会话无法在页面之间传输 - php sessions not transferring between pages 为什么这适用于 IE,但不适用于 Firefox 或 Chrome? - Why does this work for IE but not for Firefox or Chrome? 我的php注销功能在IE或FF中不起作用。 在Chrome中可完美运行 - My php logout function doesn't work in IE or FF. Works beautifully in Chrome php代码在ie上的表单提交上不起作用(但在chrome,ff上工作正常) - php code doesn`t work on form submit on ie (but works fine on chrome, ff) (PHP / JS)Google Maps API 3在IE,FF和iPad(Safari / Chrome)中未获得结果,但在Chrome&M8 Android(本机/ Chrome)中获得结果 - (PHP / JS) Google Maps API 3 not getting results in IE, FF & iPad (Safari / Chrome) but does on Chrome & M8 Android (Native / Chrome) 在Chrome和IE的iFrame中丢失PHP会话 - Losing PHP sessions in iFrame with Chrome & IE 使用会话在PHP页面之间进行数据传输 - Data transfer between php pages using sessions
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM