public function prepareResponse($request, $response) { if ($response instanceof PsrResponseInterface) { $response = (new HttpFoundationFactory)->createResponse($response); } // 若不是 \Symfony\Component\HttpFoundation\SymfonyResponse 的對象,則構形成此對象 elseif (! $response instanceof SymfonyResponse) { $response = new Response($response); } return $response->prepare($request); }
public function createResponse(ResponseInterface $psrResponse) { $response = new Response( $psrResponse->getBody()->__toString(), $psrResponse->getStatusCode(), $psrResponse->getHeaders() ); $response->setProtocolVersion($psrResponse->getProtocolVersion()); foreach ($psrResponse->getHeader('Set-Cookie') as $cookie) { $response->headers->setCookie($this->createCookie($cookie)); } return $response; } 本質就是用的 Response 類
public function __construct($content = '', $status = 200, $headers = array()) { $this->headers = new ResponseHeaderBag($headers); $this->setContent($content); $this->setStatusCode($status); $this->setProtocolVersion('1.0'); // Deprecations $class = get_class($this); if ($this instanceof \PHPUnit_Framework_MockObject_MockObject || $this instanceof \Prophecy\Doubler\DoubleInterface) { $class = get_parent_class($class); } if (isset(self::$deprecationsTriggered[$class])) { return; } self::$deprecationsTriggered[$class] = true; foreach (self::$deprecatedMethods as $method) { $r = new \ReflectionMethod($class, $method); if (__CLASS__ !== $r->getDeclaringClass()->getName()) { @trigger_error(sprintf('Extending %s::%s() in %s is deprecated since version 3.2 and won\'t be supported anymore in 4.0 as it will be final.', __CLASS__, $method, $class), E_USER_DEPRECATED); } } } public function setContent($content) { if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable(array($content, '__toString'))) { throw new \UnexpectedValueException(sprintf('The Response content must be a string or object implementing __toString(), "%s" given.', gettype($content))); } $this->content = (string) $content; return $this; } public function setStatusCode($code, $text = null) { $this->statusCode = $code = (int) $code; if ($this->isInvalid()) { throw new \InvalidArgumentException(sprintf('The HTTP status code "%s" is not valid.', $code)); } if (null === $text) { $this->statusText = isset(self::$statusTexts[$code]) ? self::$statusTexts[$code] : 'unknown status'; return $this; } if (false === $text) { $this->statusText = ''; return $this; } $this->statusText = $text; return $this; } public function isInvalid() { return $this->statusCode < 100 || $this->statusCode >= 600; } public function setProtocolVersion($version) { $this->version = $version; return $this; }
主要是設置響應頭javascript
public function prepare(Request $request) { $headers = $this->headers; // 信息類 if ($this->isInformational() || $this->isEmpty()) { $this->setContent(null); $headers->remove('Content-Type'); $headers->remove('Content-Length'); } else { if (!$headers->has('Content-Type')) { $format = $request->getRequestFormat(); # static::$formats = array( # 'html' => array('text/html', 'application/xhtml+xml'), # 'txt' => array('text/plain'), # 'js' => array('application/javascript', 'application/x-javascript', 'text/javascript'), # 'css' => array('text/css'), # 'json' => array('application/json', 'application/x-json'), # 'xml' => array('text/xml', 'application/xml', 'application/x-xml'), # 'rdf' => array('application/rdf+xml'), # 'atom' => array('application/atom+xml'), # 'rss' => array('application/rss+xml'), # 'form' => array('application/x-www-form-urlencoded'), # ); if (null !== $format && $mimeType = $request->getMimeType($format)) { $headers->set('Content-Type', $mimeType); } } // 設置編碼格式 $charset = $this->charset ?: 'UTF-8'; if (!$headers->has('Content-Type')) { $headers->set('Content-Type', 'text/html; charset='.$charset); } elseif (0 === stripos($headers->get('Content-Type'), 'text/') && false === stripos($headers->get('Content-Type'), 'charset')) { $headers->set('Content-Type', $headers->get('Content-Type').'; charset='.$charset); } // 若傳輸時用分塊編碼,則移除 Content-Length, 由於採用分塊編碼時能夠知道傳輸什麼時候完成 if ($headers->has('Transfer-Encoding')) { $headers->remove('Content-Length'); } if ($request->isMethod('HEAD')) { $length = $headers->get('Content-Length'); $this->setContent(null); if ($length) { $headers->set('Content-Length', $length); } } } if ('HTTP/1.0' != $request->server->get('SERVER_PROTOCOL')) { $this->setProtocolVersion('1.1'); } if ('1.0' == $this->getProtocolVersion() && false !== strpos($this->headers->get('Cache-Control'), 'no-cache')) { $this->headers->set('pragma', 'no-cache'); $this->headers->set('expires', -1); } $this->ensureIEOverSSLCompatibility($request); return $this; } public function isInformational() { return $this->statusCode >= 100 && $this->statusCode < 200; } protected function ensureIEOverSSLCompatibility(Request $request) { if (false !== stripos($this->headers->get('Content-Disposition'), 'attachment') && preg_match('/MSIE (.*?);/i', $request->server->get('HTTP_USER_AGENT'), $match) == 1 && true === $request->isSecure()) { if ((int) preg_replace('/(MSIE )(.*?);/', '$2', $match[0]) < 9) { $this->headers->remove('Cache-Control'); } } }