AS3 не отправляет данные POST в браузер — неправильный тип содержимого URLRequestHeader?

У меня есть следующий код в моем коде AS3 Flash, который делает снимок экрана в swf с помощью JPGEncoder и отправляет его на URL-адрес, где я записываю его в файл на PHP.

Недавно я столкнулся с проблемой Google Chrome Pepperflash, когда функция просто останавливается, и страница не перенаправляется. В save.php ничего не отправляется. Путем изменения

var header:URLRequestHeader = new URLRequestHeader ("Content-type", "application/octet-stream");

to

var header:URLRequestHeader = new URLRequestHeader ("Content-type", "text/plain");

Казалось, это помогло. На сегодняшний день это работает в Internet Explorer, но больше не работает в Chrome, Safari, Firefox. Я видел, что Adobe вчера выпустила обновление/исправление для флеш-памяти и флеш-плеера — может ли это иметь какое-то отношение к этому?

Если я удалю следующее:

var header:URLRequestHeader = new URLRequestHeader ("Content-type", "text/plain"); 
jpgURLRequest.requestHeaders.push(header);   

Затем страница успешно перенаправляется, но $GLOBALS['HTTP_RAW_POST_DATA'] становится пустой, поэтому файл изображения не может быть создан.

Могу ли я поставить альтернативный заголовок, который решит эту проблему?

Мой код:

AS3:

function createJPG(m:MovieClip, q:Number, fileName:String) {
    var jpgSource:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight);
    jpgSource.draw(stage);
    var jpgScreenshot: BitmapData = new BitmapData(362, 310);
    jpgScreenshot.copyPixels(jpgSource, new Rectangle(288, 89, 362, 310), new Point(0, 0));
    var jpgEncoder:JPGEncoder = new JPGEncoder(q);
    var jpgStream:ByteArray = jpgEncoder.encode(jpgScreenshot);

    var header:URLRequestHeader = new URLRequestHeader ("Content-type", "text/plain");

    var jpgURLRequest:URLRequest = new URLRequest ("http://www.url.com/save.php");      
    jpgURLRequest.requestHeaders.push(header);              
    jpgURLRequest.method = URLRequestMethod.POST;               
    jpgURLRequest.data = jpgStream;
    var jpgURLLoader:URLLoader = new URLLoader();   
    navigateToURL(jpgURLRequest, "_self");
}

сохранить.php

$imagefile=''.$imageURL.'';
$fp = fopen($imagefile, 'wb');
fwrite($fp, $GLOBALS['HTTP_RAW_POST_DATA']);
fclose($fp);

header('Location: https://www.url.com/your-image.php');

person odd_duck    schedule 15.05.2014    source источник


Ответы (3)


Удалось заставить это работать сейчас со следующим кодом. Лиам был прав в вопросе о Flash Player. Теперь работаем, разделив сохранение изображения и переход по URL-адресу на две разные функции:

function createJPG(m:MovieClip, q:Number, fileName:String) {
    var jpgSource:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight);
    jpgSource.draw(stage);
    var jpgScreenshot: BitmapData = new BitmapData(362, 310);
    jpgScreenshot.copyPixels(jpgSource, new Rectangle(288, 89, 362, 310), new Point(0, 0));
    var jpgEncoder:JPGEncoder = new JPGEncoder(q);
    var jpgStream:ByteArray = jpgEncoder.encode(jpgScreenshot);

    var urlLoader:URLLoader = new URLLoader();
    var header:URLRequestHeader = new URLRequestHeader("Content-type", "application/octet-stream");
    var saveJPG:URLRequest = new URLRequest('http://www.url.com/save_image.php?name=filename';
    saveJPG.requestHeaders.push(header);
    saveJPG.method = URLRequestMethod.POST;
    saveJPG.data = jpgStream;   
    urlLoader.addEventListener(Event.COMPLETE, goToCheckout);
    urlLoader.load(saveJPG);
}

function goToCheckout(e:Event):void{
    var url:String = 'http://www.url.com/show_image.php';
    var request:URLRequest = new URLRequest(url);
    try {
      navigateToURL(request, '_self'); 
    } catch (e:Error) {
      trace("Error occurred!:");
    }
}

save_image.php:

if(isset($GLOBALS["HTTP_RAW_POST_DATA"])){
    $jpg = $GLOBALS["HTTP_RAW_POST_DATA"];
    $path = "";
    $id = $_GET["name"];
    $file = $id;
    file_put_contents($path.$file, $jpg);
    echo "complete";
} else{
    // error
}
person odd_duck    schedule 15.05.2014

Flash Player версии 13.0.0.214 содержит ряд важных исправлений безопасности. К сожалению, он также нарушает работу navigationToUrl(), запрещая изменение любых заголовков в запросе, переданном для navigationToUrl(). Это прерывает POST-запросы, которые необходимо передать в заголовках токенов безопасности/сеанса или даже изменить Content-Type, например. в text/xml и т. д., как вы сделали в своем примере.

Прямо сейчас, как бы это ни было отстойно, наш самый известный обходной путь — понизить версию клиентов до 13.0.0.206.

person Liam Bowers    schedule 15.05.2014
comment
теперь это работает с моим ответом ниже, может быть, это может вам помочь? - person odd_duck; 15.05.2014
comment
В Adobe была зарегистрирована ошибка, поскольку изменение, внесенное в 13.0.0.214, может быть слишком строгим. Проголосуйте за него: bugbase.adobe.com/index.cfm?event=bug&id= 3759971 - person Chris; 19.05.2014

Adobe предлагает использовать вызов внешнего интерфейса, как описано здесь: https://forums.adobe.com/message/6396080 он использует JavaScript для замены метода POST

Однако решение, предложенное odd_duck, кажется более простым - было бы здорово увидеть и код php.

person Fred    schedule 21.05.2014
comment
Отредактировал мой ответ выше, чтобы включить php для вас - person odd_duck; 21.05.2014