[PHP cURL]: сеансовые куки не сохраняются? - PullRequest
0 голосов
/ 01 сентября 2018

Я расширяю php-скрипт, который проверяет, включен ли javascript, чтобы перезагружать его после второго раза (когда js, похоже, выключен). Вот ссылка на оригинальный скрипт php от erm3nda . Как видно из его фрагмента, при первой загрузке страницы скрипт (более того, «вызывающий») печатает тег скрипта с запросом jquery ajax на той же странице, но с заголовком $_GET, который перехватывается та же страница загружается в фоновом режиме (далее называемый «скрипт») и устанавливает переменную $_SESSION в 1. После того, как вызываемый скрипт завершает свою работу в фоновом режиме, вызывающая сторона перезагружается (и снова вызывает этот ajax-запрос), пока не сможет найдите переменную $_SESSION с тем же именем, которая должна быть установлена ​​в 1. Если этого не произойдет, она завершится во время процесса перезагрузки с «javascript is disabled», если она была установлена ​​на 1, она завершится с «javascript is enabled». Я начал изменять этот код, чтобы перестать перезагружать страницу после того, как она уже была перезагружена один раз. Поэтому в настоящее время я использую этот скрипт:

test.php

<html><body><?php
header('Content-Type: text/html; charset=utf-8');
ini_set('display_errors', 1);
ini_set('log_errors',1);
ini_set('display_startup_errors', 1);
ini_set('error_reporting', E_ALL);
error_reporting(E_ALL);
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
function start_session() {
  if(version_compare(phpversion(), "5.4.0") != -1){
    if (session_status() == PHP_SESSION_NONE) {
      session_start();
    }
  } else {
    if(session_id() == '') {
      session_start();
    }
  }
}
start_session();
if (!isset($_SESSION['js']) && !isset($_REQUEST['sessionstart']) && !isset($_REQUEST['setjsoff']) && !isset($_SESSION['jsoff'])) {
  echo '<script src="./js/jquery.js"></script><script type="text/javascript">$(document).ready(function(){$.get(document.URL.substring() + "?sessionstart=1");});</script>';
}
if (isset($_REQUEST['sessionstart'])) {
  $_SESSION['js'] = 1;
  exit("in sessionstart mode");
} else {
  if (isset($_REQUEST['setjsoff'])) {
    $_SESSION['jsoff'] = 1;
    if ($_SESSION['jsoff'] == 1) {
      exit("in setjsoff mode (success)");
    } else {
      exit("jsoff unsuccessful");
    }
  } else {
    session_destroy();
  }
}
if (!isset($_SESSION['js'])) {
  if (!isset($_SESSION['jsoff'])) {
    if (!isset($_REQUEST['sessionstart'])) {
      $ch = curl_init();
      $username = "***";
      $password = "***";
      curl_setopt($ch, CURLOPT_URL, "***/test.php?setjsoff=1");
      curl_setopt($ch, CURLOPT_HEADER, true);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
      curl_setopt($ch, CURLOPT_FORBID_REUSE, true);
      curl_setopt($ch, CURLOPT_HTTPGET, true);
      curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
      curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
      $chout = curl_exec($ch);
      curl_close($ch);
      echo "curl init - ".$chout." - ";
    }
    header("Refresh: 1");
    exit("301 Redirect");
  }
  echo "Javascript is not enabled";
} else {
  echo "Javascript is enabled";
}
?></body></html>

(конфиденциальная информация была заменена на ***)

При включенном javascript этот сценарий в настоящее время функционирует следующим образом: он загружается, перезагружается один раз, и вызывающая сторона выдает «javascript is enabled».
Без включенного JavaScript, вызывающая сторона загружает, перезагружает и выводит эту информацию во время перезагрузки (намеренно): "curl init - HTTP/1.1 200 OK Date: *** GMT Server: Apache X-Powered-By: PHP/5.6.36 Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Set-Cookie: PHPSESSID=***; path=/ Transfer-Encoding: chunked Content-Type: text/html; charset=utf-8 in setjsoff mode (success) - 301 Redirect".

(конфиденциальная информация была заменена на ***)

Как видите, вывод делится на 3 части:
- curl init сигнализирует о том, что завиток инициирован (без вывода ошибки)
- the header information of the called page via curl + output of that page
- 301 redirect сигнализирует, что страница полностью выполнена и собирается перезагрузить

Заголовок является наиболее важным полученным сообщением, поскольку он в основном раскрывает то, что произошло в фоновом режиме. Похоже, что curl называется страницей, страница возвращает in setjsoff mode (success) (что означает, что она установила $_SESSION['js'] в 1) и очень много информации заголовка, которую я не могу интерпретировать.
Вот (наконец) моя проблема : страница продолжает перезагружаться после этого (так что переменная сеанса была как-то потеряна?). Показывает ли информация в заголовке какие-либо проблемы, или я забыл установить необходимую опцию через curl_setopt?

1 Ответ

0 голосов
/ 01 сентября 2018

Основная проблема в том, что вы не фактически перезагружаете страницу. Возможно, вы заставляете сервер перейти на ту же страницу, но это совершенно другой сеанс по сравнению с исходным сеансом клиента, который его инициировал. Кроме того, вы не указываете cookie-файл для curl, поэтому, даже если вы могли ухитриться восстановить его, ваш сеанс и связанные cookie-файлы из-за вызова на сервере будут потеряны.

Первый пункт, однако, является фундаментальной проблемой: вы пытаетесь сделать что-то, о чем вам даже не следует думать. К счастью, спецификация HTML предлагает вам элемент <noscript>, с которым вы можете работать.

Так что просто испустите что-то вроде этого:

<script type="text/javascript">/*<![CDATA[*/ 
/* JS code goes here  */ 
/*]]>*/</script>
<noscript>
  <!--
    - hit a PHP endpoint that returns a static resource you can hide
    - that PHP script can adjust the session as necessary.
   -->
  <img src="/dummy/image/script.php?jsoff=1" 
       style="width:0px!important;height:0px!important;">
</noscript>

Еще лучше: почему бы просто не предположить, что JavaScript не доступен, а затем пересмотреть это, когда будет запущен отдельный скрипт PHP? Затем вы можете просто связать статический ресурс <script> на странице <head> ... В общем, гораздо более простое и надежное решение.

...