2016-08-22 5 views
1

Это убивает меня.Переменные сеанса PHP не доступны при эмуляции приложения Cordova

Я создаю мобильное приложение с помощью apache cordova, где jQuery AJAX и PHP используются для связи с сервером и базой данных. Я впервые обнаружил эту проблему, когда сталкивался с ошибками, которых не было у моих товарищей по команде, и мы использовали один и тот же код. В некоторых наших PHP-кодеках мы использовали переменные $_SESSION для хранения данных, но при правильном использовании приложения на моем компьютере оно не сохраняется должным образом. Вот пример кода, который не работает:

<?php 

header('Access-Control-Allow-Origin : *'); 
include 'connection.php'; 

$userId = $_SESSION["userId"]; 

$query = "SELECT * ". 
     "FROM `db`.`users` ". 
     "WHERE `userId` = $userId;"; 

$result = $conn->query($query); 
$result_array = array(); 
while($row = mysqli_fetch_assoc($result)) 
{ 
    $result_array[] = $row; 
} 
echo json_encode($result_array); 

На странице, которая проходит перед этим, другой файл PHP называется содержащий эту строку:

$_SESSION["userId"] = $userId;

include connection.php содержит все наш пользователь/логин, а также session_start();. Обходной путь был следующим: эта ошибка не возникает, когда я создаю приложение и тестирую его на устройстве. Это происходит только на моей машине при отладке приложения через эмулятор ряби в окне браузера Chrome. Поскольку я не хотел создавать новую сборку так часто, я изменил наш код, чтобы сохранить данные на лицевой стороне, используя sessionStorage и должен был отключить настройку Cross Domain Proxy на эмуляторе.

Это то, где я считаю, что ошибка: ни один из моих вызовов AJAX не выполняется, если я не установил прокси-сервер Cross Domain на «Disabled», но если я это сделаю, PHP $_SESSION больше не работает (я обнаружил, что идентификатор сеанса просто сбрасывает каждый новый вызов). Мой товарищ по команде может отлично отлаживать эмулятор, а его Cross Domain Proxy установлен на «Local». Когда я пытаюсь это сделать, все мои AJAX снова вызывают ошибку.

Также - последнее, что нужно отметить: когда я запускаю приложение только в веб-браузере, не используя эмулятор пульсации или что-то еще, все работает отлично. Который сузил бы проблему до чего-то конкретно с эмулятором ряби.

Я относительно новичок в этом вопросе - запросы CORS и AJAX, но я сделал некоторые серьезные исследования перед публикацией здесь - это мое последнее средство. Я буду часто следить за этим вопросом, если вам понадобится что-нибудь еще, чтобы помочь мне решить эту проблему. Благодаря!

EDIT: Ниже ошибка я получаю, когда я бегу ripple emulate из командной строки после выполнения некоторых из предложенных изменений, это та же самая ошибка, я получаю раньше:

C:\Users\Brian\Documents\HoH Docs\Source Code\gitDev\HoH\www>ripple emulate 
INFO: Server instance running on: http://localhost:4400 
INFO: CORS XHR proxy service on: http://localhost:4400/ripple/xhr_proxy 
INFO: JSONP XHR proxy service on: http://localhost:4400/ripple/jsonp_xhr_proxy 
INFO: Could not find cordova as a local module. Expecting to find it installed g 
lobally. 
INFO: Using Browser User Agent (String) 
INFO: Proxying cross origin XMLHttpRequest - http://www.server.com/php/ 
[email protected]&password=test 
_http_outgoing.js:347 
     throw new TypeError(
    ^

TypeError: Trailer name must be a valid HTTP Token ["access-control-allow-origin 
"] 
    at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:347:13) 
    at ServerResponse.res.setHeader (C:\Users\Brian\AppData\Roaming\npm\node_mod 
ules\ripple-emulator\node_modules\express\node_modules\connect\lib\patch.js:59:2 
2) 
    at Request.pipeDest (C:\Users\Brian\AppData\Roaming\npm\node_modules\ripple- 
emulator\node_modules\request\main.js:723:12) 
    at C:\Users\Brian\AppData\Roaming\npm\node_modules\ripple-emulator\node_modu 
les\request\main.js:614:14 
    at Array.forEach (native) 
    at ClientRequest.<anonymous> (C:\Users\Brian\AppData\Roaming\npm\node_module 
s\ripple-emulator\node_modules\request\main.js:613:18) 
    at ClientRequest.g (events.js:260:16) 
    at emitOne (events.js:77:13) 
    at ClientRequest.emit (events.js:169:7) 
    at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:433:21 
) 

И получить это от веб Debugger Fiddler, когда запрос был сделан:

The connection to 'localhost' failed. <br />Error: ConnectionRefused (0x274d). <br />System.Net.Sockets.SocketException No connection could be made because the target machine actively refused it 127.0.0.1:4400                                                                          
+0

$ _SESSION по умолчанию работает с файлом cookie, который хранит в браузере идентификатор сеанса. Этот идентификатор файла cookie нормально отправляется каждый раз в заголовке, когда браузер вызывает скрипт. Более того, когда вы делаете вызов CORS, заголовок должен быть с разрешенным. Поэтому я считаю, что будет неплохо пойти посмотреть заголовок, который используется в вашем приложении или на вашем сервере. –

+0

Как мне увидеть заголовок? – brdeav39

+0

У вас есть доступ к нему в инструменте chrome dev в сетевом разделе. –

ответ

1

Это, скорее всего, ваша проблема:

header('Access-Control-Allow-Origin : *'); 
include 'connection.php'; 

Вы отправляете заголовки в браузер, прежде чем включать файл подключения, в котором вы начинаете сеанс.

В некоторых средах тестирования выходная буферизация может быть включена, поэтому это сработает. Однако в вашей среде кажется, что это не так, ваш session_start() в connection.php не удастся.

Вы не должны ничего выводить в браузер перед вызовом session_start() так что в этом случае вы должны переместить header() вызов ниже, включают:

include 'connection.php'; 
header('Access-Control-Allow-Origin : *'); 

Вы, вероятно, может проверить, что это проблема в журнал ошибок сервера.

+0

Я только что проверил это, но все равно получаю ту же проблему. – brdeav39

+0

Я добавил некоторые из моих ошибок в EDIT. – brdeav39

0

Вы можете быть должны установить header в вашем АЯКС запросе

если ваш используя метод Ajax JQuery добавьте ниже вариант

xhrFields: { 
    withCredentials: true 
} 

Или, если вы отправляете AJAX запрос с помощью объекта XMLHttpRequest, то он должен быть что-то вроде belwo

var xhr = new XMLHttpRequest(); 
xhr.open('GET', 'http://example.com/', true); 
xhr.withCredentials = true; 
xhr.send(null); 

XMLHttpRequest ответов из другого домена са nnot установить cookie значения для собственного домена, если только для параметра Credentials установлено значение перед выполнением запроса, независимо от заголовка Access-Control- .

+0

Просто протестировал это, но я все равно получаю тот же результат. Я только что добавил редактирование с ошибками, которые я получаю – brdeav39

+0

попробуйте с crossDomain: true, in ajax –

+0

Все еще получаю ту же проблему ... это очень запутанно. – brdeav39