Čtení cookies a podivná prodleva – nutný refresh stránky? – log zahrnut

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
nettolog
Člen | 68
+
0
-

Dobrý večer,

řeším problém s prodlevou ve čtení cookies. Potřebuji v případě 404 stránky zobrazit homepage a vykreslit chybu ohledně neexistující stránky. V ErrorPresenteru tedy před nastavím cookies a poté forward na homepage. BasePresenter hned po forwardu cookie nevidí, vidí je až po znovu načtení. Přitom je cookies v pořádku okamžitě nastavena (prohlížeč ji vidí). Nesetkali jste se s tím někdo? Vím, že na notifikace asi všichni používáte flashmessages, ale já bych raději řešení bez parametru _fid v url, takže vždy nastavím cookie na 5 vteřin s id zprávy a tu pak načtu a vykreslím. Nebo vás na to napadá lepší řešení?
Díky za případné rady a postřehy.

Log toho řekne asi víc:

[2015-08-02 17-20-08] před nastavením cookie  @  http://example.com/neexistujici_stranka
[2015-08-02 17-20-08] ID notifikace: NULL  @  http://example.com/neexistujici_stranka
[2015-08-02 17-20-08] Cookies: array ( 'PHPSESSID' => 'c8e2a18349a39de5572b46dbf9ab8658', 'nette-browser' => 'k8nkqj85nx', '_ga' => 'GA1.2.1751031182.1438378106', '_gat' => '1', )  @  http://example.com/neexistujici_stranka

[2015-08-02 17-20-08] Cookie notify nastavena (hodnota: 404)!  @  http://example.com/neexistujici_stranka

[2015-08-02 17-20-08] po nastavení cookie  @  http://example.com/neexistujici_stranka
[2015-08-02 17-20-08] ID notifikace: NULL  @  http://example.com/neexistujici_stranka
[2015-08-02 17-20-08] Cookies: array ( 'PHPSESSID' => 'c8e2a18349a39de5572b46dbf9ab8658', 'nette-browser' => 'k8nkqj85nx', '_ga' => 'GA1.2.1751031182.1438378106', '_gat' => '1', )  @  http://example.com/neexistujici_stranka

[2015-08-02 17-20-08] Vykreslení notifikace po forwardu  @  http://example.com/neexistujici_stranka
[2015-08-02 17-20-08] ID notifikace: NULL  @  http://example.com/neexistujici_stranka
[2015-08-02 17-20-08] Cookies: array ( 'PHPSESSID' => 'c8e2a18349a39de5572b46dbf9ab8658', 'nette-browser' => 'k8nkqj85nx', '_ga' => 'GA1.2.1751031182.1438378106', '_gat' => '1', )  @  http://example.com/neexistujici_stranka


[2015-08-02 17-20-10] Manuální načtení homepage  @  http://example.com/ (pozn. cookie má expiraci 5 vteřin, takže je správně, že se tady ukázala, ale měla se ukázat už v předchozím požadavku)
[2015-08-02 17-20-10] ID notifikace: '404'  @  http://example.com/
[2015-08-02 17-20-10] Cookies: array ( '_ga' => 'GA1.2.1751031182.1438378106', '_gat' => '1', 'PHPSESSID' => 'c8e2a18349a39de5572b46dbf9ab8658', 'nette-browser' => 'k8nkqj85nx', 'notify' => '404', )  @  http://example.com/

Pokud byste se chtěli podívat na error presenter, tak ten mám tady: https://forum.nette.org/…-na-homepage#…

Editoval nettolog (2. 8. 2015 17:35)

nettolog
Člen | 68
+
0
-

Aha, opravdu to tak je. Naštěstí to jde celkem snadno vyřešit – kdyby to někdo taky řešil, tak při nastavení cookies provést i $_COOKIE['name'] = "val";.

Editoval nettolog (2. 8. 2015 18:11)

CZechBoY
Člen | 3608
+
0
-

Řekl bych, že to je to stejná chyba jako v mém případě.
Jako parametr funkce forward dej Request a mělo by to jet.
https://forum.nette.org/…a-dat-v-post

Editoval CZechBoY (2. 8. 2015 18:18)

Filip Procházka
Moderator | 4668
+
+1
-

Je to proto, že Http\Request se vytvoří na základě prvního requestu, né na základě toho co pošleš zpátky do browseru. A je to tak správně.

V aplikaci používáme tuto třídu (registrovanou jako službu), která to řeší. Je potřeba si ale uvědomit ten rozdíl mezi použitím.

class Cookies
{
	/**
	 * @var Http\Request
	 */
	private $httpRequest;

	/**
	 * @var Http\Response
	 */
	private $httpResponse;

	/**
	 * @var string
	 */
	private $cookieDomain;

	/**
	 * @var array
	 */
	private $cookies = [];



	public function __construct(Http\Response $httpResponse, Http\IRequest $httpRequest)
	{
		$this->httpRequest = $httpRequest;
		$this->httpResponse = $httpResponse;

		$this->cookies = $this->httpRequest->getCookies();
		$this->cookieDomain = self::resolveDomain($this->httpRequest->getUrl()->getHost());
	}



	/**
	 * @return string
	 */
	public function getDomain()
	{
		return $this->cookieDomain;
	}



	public function set($name, $value, $ttl, $secure = NULL, $httpOnly = NULL)
	{
		$this->httpResponse->setCookie($name, $value, $ttl, '/', $this->cookieDomain, $secure, $httpOnly);

		if (DateTime::from($ttl) > new DateTime()) {
			$this->cookies[$name] = $value;

		} else {
			unset($this->cookies[$name]);
		}
	}



	public function remove($name, $secure = NULL, $httpOnly = NULL)
	{
		$this->set($name, FALSE, 0, $secure, $httpOnly);
	}



	/**
	 * @param string $name
	 * @param mixed $default
	 * @return NULL|string
	 */
	public function get($name, $default = NULL)
	{
		return isset($this->cookies[$name]) ? $this->cookies[$name] : $default;
	}



	public static function resolveDomain($host)
	{
		if (Strings::match($host, '~^[0-9\.]+$~')) {
			return $host;
		}

		return ($hostMatches = Strings::match($host, '~^(?:.*\.)?(?P<domain>\w+\.\w+)$~')) ? "." . $hostMatches["domain"] : NULL;
	}

}