Browse Source

Fix #17434: Fixed Internet Explorer 11 AJAX redirect bug in case of 301 and 302 response codes (`XMLHttpRequest: Network Error 0x800c0008`)

tags/2.0.26
Somogyi Márton 5 years ago committed by Alexander Makarov
parent
commit
10a069a3a4
  1. 1
      framework/CHANGELOG.md
  2. 10
      framework/web/Response.php
  3. 48
      tests/framework/web/ResponseTest.php
  4. 77
      tests/framework/web/mocks/TestRequestComponent.php

1
framework/CHANGELOG.md

@ -10,6 +10,7 @@ Yii Framework 2 Change Log
- Bug #16305: Fix `FileValidator` mime-type validation failure because of case sensitivity (kamarton)
- Bug #17355: Fixed Pjax after request event bug (kamarton)
- Bug #17522: `DbManager::isEmptyUserId()` is now protected (samdark)
- Bug #17434: Fixed Internet Explorer 11 AJAX redirect bug in case of 301 and 302 response codes (`XMLHttpRequest: Network Error 0x800c0008`) (kamarton)
2.0.25 August 13, 2019

10
framework/web/Response.php

@ -857,18 +857,18 @@ class Response extends \yii\base\Response
// ensure the route is absolute
$url[0] = '/' . ltrim($url[0], '/');
}
$request = Yii::$app->getRequest();
$url = Url::to($url);
if (strncmp($url, '/', 1) === 0 && strncmp($url, '//', 2) !== 0) {
$url = Yii::$app->getRequest()->getHostInfo() . $url;
$url = $request->getHostInfo() . $url;
}
if ($checkAjax) {
if (Yii::$app->getRequest()->getIsAjax()) {
if (Yii::$app->getRequest()->getHeaders()->get('X-Ie-Redirect-Compatibility') !== null && $statusCode === 302) {
// Ajax 302 redirect in IE does not work. Change status code to 200. See https://github.com/yiisoft/yii2/issues/9670
if ($request->getIsAjax()) {
if (in_array($statusCode, [301, 302]) && preg_match('/Trident.*\brv\:11\./' /* IE11 */, $request->userAgent)) {
$statusCode = 200;
}
if (Yii::$app->getRequest()->getIsPjax()) {
if ($request->getIsPjax()) {
$this->getHeaders()->set('X-Pjax-Url', $url);
} else {
$this->getHeaders()->set('X-Redirect', $url);

48
tests/framework/web/ResponseTest.php

@ -10,9 +10,12 @@ namespace yiiunit\framework\web;
use Error;
use Exception;
use RuntimeException;
use Yii;
use yii\helpers\StringHelper;
use yii\web\HttpException;
use yii\web\Request;
use yii\web\Response;
use yiiunit\framework\web\mocks\TestRequestComponent;
/**
* @group web
@ -27,7 +30,13 @@ class ResponseTest extends \yiiunit\TestCase
protected function setUp()
{
parent::setUp();
$this->mockWebApplication();
$this->mockWebApplication([
'components' => [
'request' => [
'class' => TestRequestComponent::className(),
],
],
]);
$this->response = new \yii\web\Response();
}
@ -134,6 +143,43 @@ class ResponseTest extends \yiiunit\TestCase
}
/**
* @dataProvider dataProviderAjaxRedirectInternetExplorer11
*/
public function testAjaxRedirectInternetExplorer11($userAgent, $statusCodes) {
$_SERVER['REQUEST_URI'] = 'http://test-domain.com/';
$request= Yii::$app->request;
/* @var $request TestRequestComponent */
$request->getIssAjaxOverride = true;
$request->getUserAgentOverride = $userAgent;
foreach([true, false] as $pjaxOverride) {
$request->getIsPjaxOverride = $pjaxOverride;
foreach(['GET', 'POST'] as $methodOverride) {
$request->getMethodOverride = $methodOverride;
foreach($statusCodes as $statusCode => $expectStatusCode) {
$this->assertEquals($expectStatusCode, $this->response->redirect(['view'], $statusCode)->statusCode);
}
}
}
}
/**
* @link https://blogs.msdn.microsoft.com/ieinternals/2013/09/21/internet-explorer-11s-many-user-agent-strings/
* @link https://stackoverflow.com/a/31279980/6856708
* @link https://developers.whatismybrowser.com/useragents/explore/software_name/chrome/
* @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent/Firefox
* @return array
*/
public function dataProviderAjaxRedirectInternetExplorer11() {
return [
['Mozilla/5.0 (Android 4.4; Mobile; rv:41.0) Gecko/41.0 Firefox/41.0', [301 => 301, 302 => 302]], // Firefox
['Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko', [301 => 200, 302 => 200]], // IE 11
['Mozilla/5.0 (Windows NT 6.3; Trident/7.0; .NET4.0E; .NET4.0C; rv:11.0) like Gecko', [301 => 200, 302 => 200]], // IE 11
['Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36', [301 => 301, 302 => 302]], // Chrome
['Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10136', [301 => 301, 302 => 302]], // Edge
];
}
/**
* @dataProvider dataProviderSetStatusCodeByException
* @param \Exception $exception
* @param int $statusCode

77
tests/framework/web/mocks/TestRequestComponent.php

@ -0,0 +1,77 @@
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yiiunit\framework\web\mocks;
use yii\web\Request;
class TestRequestComponent extends Request
{
/**
* @var bool|null override getIsAjax() method return value
*/
public $getIssAjaxOverride;
/**
* @var string|null override getMethod() method return value
*/
public $getMethodOverride;
/**
* @var string|null override getUserAgent() method return value
*/
public $getUserAgentOverride;
/**
* @var bool|null override getIsPjax() method return value
*/
public $getIsPjaxOverride;
/**
* @inheritDoc
*/
public function getMethod()
{
if($this->getMethodOverride !== null) {
return $this->getMethodOverride;
}
return parent::getMethod(); // TODO: Change the autogenerated stub
}
/**
* @inheritDoc
*/
public function getIsAjax()
{
if ($this->getIssAjaxOverride !== null) {
return $this->getIssAjaxOverride;
}
return parent::getIsAjax();
}
/**
* @inheritDoc
*/
public function getIsPjax()
{
if ($this->getIsPjaxOverride !== null) {
return $this->getIsPjaxOverride;
}
return parent::getIsPjax();
}
/**
* @inheritDoc
*/
public function getUserAgent()
{
if($this->getUserAgentOverride !== null) {
return $this->getUserAgentOverride;
}
return parent::getUserAgent();
}
}
Loading…
Cancel
Save