2013-08-21 6 views
3

Теперь я пытаюсь настроить fineuploader-s3, чтобы показать изображение файла, успешно загруженного на сервер aws, как это было сделано на странице примера здесь: http://fineuploader.com/#s3-demoпроблема с отображением изображения, загруженного в Amazon s3 fine-uploader

Я (все еще), используя код на https://github.com/Widen/fine-uploader-server/blob/master/php/s3/s3demo.php, и я добавил

uploadSuccess: { 
     endpoint: "s3demo.php?success" 
    } 

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

Я понял, что мне пришлось установить AWS SDK, чтобы заставить его работать. Метод установки zip действительно не работает, поэтому я использую phar. я изменил этот раздел файла s3demo.php к:

require 'aws.phar'; 
use Aws\S3\S3Client; 

Я также раскомментировать эти две линии:

$serverPublicKey = $_SERVER['PARAM1']; 
$serverPrivateKey = $_SERVER['PARAM2']; 

У меня возникают две проблемы в получении это work.The первым в том, что что-то идет не так с моим ответом на успех от AWS, из которого я думаю, что я должен получить ссылку на файл.

Файл загрузки отлично, но я получаю сообщение об ошибке в консоли:

[FineUploader 3.8.0] Sending POST request for 0 s3.jquery.fineuploader-3.8.0.js:164 
[FineUploader 3.8.0] Received the following response body to an AWS upload success request for id 0: <br /> 
<b>Fatal error</b>: Uncaught exception 'Guzzle\Http\Exception\CurlException' with message '[curl] 28: Connection timed out after 1001 milliseconds [url] http://169.254.169.254/latest/meta-data/iam/security-credentials/' in phar:///MYSITE/aws.phar/Guzzle/Http/Curl/CurlMulti.php:339 
Stack trace: 
#0 phar:///MYSITE//aws.phar/Guzzle/Http/Curl/CurlMulti.php(280): Guzzle\Http\Curl\CurlMulti-&gt;isCurlException(Object(Guzzle\Http\Message\Request), Object(Guzzle\Http\Curl\CurlHandle), Array) 
#1 phar:///MYSITE//aws.phar/Guzzle/Http/Curl/CurlMulti.php(245): Guzzle\Http\Curl\CurlMulti-&gt;processResponse(Object(Guzzle\Http\Message\Request), Object(Guzzle\Http\Curl\CurlHandle), Array) 
#2 phar:///MYSITE//aws.phar/Guzzle/Http/Curl/CurlMulti.php(228): Guzzle\Http\Curl\CurlMulti-&gt;processMessages() 
#3 phar:///MYSITE//aws.phar/Guzzle/Http/Curl/CurlMulti.php(212): Guzzle\Http\Curl\CurlMulti-&gt;executeHandles() 
#4 phar:///MYSITE/z/aw in <b>phar:///home/nextq2/public_html/lenz/aws.phar/Aws/Common/InstanceMetadata/InstanceMetadataClient.php</b> on line <b>82</b><br /> 
s3.jquery.fineuploader-3.8.0.js:164 
[FineUploader 3.8.0] Upload success was acknowledged by the server. s3.jquery.fineuploader-3.8.0.js:164 

Означает ли это, что-то не так с моей установки AWS SDK, или в моих настройках разрешений на Amazon? Для настроек CORS и IAM? Какой еще следующим образом:

<CORSRule> 
     <AllowedOrigin>MY WEBSITE</AllowedOrigin> 
     <AllowedMethod>POST</AllowedMethod> 
     <MaxAgeSeconds>3000</MaxAgeSeconds> 
     <AllowedHeader>*</AllowedHeader> 
    </CORSRule> 

моей групповая политика на IAM:

{ 
     "Version":"2012-10-17", 
     "Statement":[{ 
     "Effect":"Allow", 
     "Action":"s3:PutObject", 
     "Resource":"arn:aws:s3:::MY_BUCKET/*” 
     }] 
} 

Второй вопрос, который я уверен, что я должен быть в состоянии понять, но не могу, это как войдите в json-массив, сгенерированный s3demo.php в моем javascript, чтобы я мог отображать загруженное изображение. Я думаю, что это не $ templink [0]. Мне было интересно, можно ли увидеть пример кода, который дает кнопку вида на http://fineuploader.com/#s3-demo его функции. Если мне стоит задать второй вопрос, я с удовольствием сделаю это.

Большое спасибо за ваше время.

EDIT, чтобы добавить свой полный код с просьбой:

PHP:

<?php 
/** 
* PHP Server-Side Example for Fine Uploader S3. 
* Maintained by Widen Enterprises. 
* 
* Note: This is the exact server-side code used by the S3 example 
* on fineuploader.com. 
* 
* This example: 
* - handles both CORS and non-CORS environments 
* - handles delete file requests for both DELETE and POST methods 
* - Performs basic inspections on the policy documents and REST headers before signing them 
* - Ensures again the file size does not exceed the max (after file is in S3) 
* - signs policy documents (simple uploads) and REST requests 
* (chunked/multipart uploads) 
* 
* Requirements: 
* - PHP 5.3 or newer 
* - Amazon PHP SDK (only if utilizing the AWS SDK for deleting files or otherwise examining them) 
* 
* If you need to install the AWS SDK, see http://docs.aws.amazon.com/aws-sdk-php-2/guide/latest/installation.html. 
*/ 

// You can remove these two lines if you are not using Fine Uploader's 
// delete file feature 

require 'aws/aws-autoloader.php'; 
use Aws\S3\S3Client; 


// These assume you have the associated AWS keys stored in 
// the associated system environment variables 
$clientPrivateKey = ‘I put my private key here; 
// These two keys are only needed if the delete file feature is enabled 
// or if you are, for example, confirming the file size in a successEndpoint 
// handler via S3's SDK, as we are doing in this example. 
$serverPublicKey = $_SERVER['PARAM1']; 
$serverPrivateKey = $_SERVER['PARAM2']; 

$expectedMaxSize = 15000000; 
$expectedBucket = “my bucket name here; 

$method = getRequestMethod(); 

// This first conditional will only ever evaluate to true in a 
// CORS environment 
if ($method == 'OPTIONS') { 
    handlePreflight(); 
} 
// This second conditional will only ever evaluate to true if 
// the delete file feature is enabled 
else if ($method == "DELETE") { 
    // handlePreflightedRequest(); // only needed in a CORS environment 
    deleteObject(); 
} 
// This is all you really need if not using the delete file feature 
// and not working in a CORS environment 
else if ($method == 'POST') { 
    handlePreflightedRequest(); 

    // Assumes the successEndpoint has a parameter of "success" associated with it, 
    // to allow the server to differentiate between a successEndpoint request 
    // and other POST requests (all requests are sent to the same endpoint in this example). 
    // This condition is not needed if you don't require a callback on upload success. 
    if (isset($_REQUEST["success"])) { 
     verifyFileInS3(); 
    } 
    else { 
     signRequest(); 
    } 
} 

// This will retrieve the "intended" request method. Normally, this is the 
// actual method of the request. Sometimes, though, the intended request method 
// must be hidden in the parameters of the request. For example, when attempting to 
// send a DELETE request in a cross-origin environment in IE9 or older, it is not 
// possible to send a DELETE request. So, we send a POST with the intended method, 
// DELETE, in a "_method" parameter. 
function getRequestMethod() { 
    global $HTTP_RAW_POST_DATA; 

    // This should only evaluate to true if the Content-Type is undefined 
    // or unrecognized, such as when XDomainRequest has been used to 
    // send the request. 
    if(isset($HTTP_RAW_POST_DATA)) { 
     parse_str($HTTP_RAW_POST_DATA, $_POST); 
    } 

    if ($_POST['_method'] != null) { 
     return $_POST['_method']; 
    } 

    return $_SERVER['REQUEST_METHOD']; 
} 

// Only needed in cross-origin setups 
function handlePreflightedRequest() { 
    // If you are relying on CORS, you will need to adjust the allowed domain here. 
    //header('Access-Control-Allow-Origin: http://nextquestion.org'); 
} 

// Only needed in cross-origin setups 
function handlePreflight() { 
    handlePreflightedRequest(); 
    header('Access-Control-Allow-Methods: POST'); 
    header('Access-Control-Allow-Headers: Content-Type'); 
} 

function getS3Client() { 
    global $serverPublicKey, $serverPrivateKey; 

    return S3Client::factory(array(
     'key' => $serverPublicKey, 
     'secret' => $serverPrivateKey 
    )); 
} 

// Only needed if the delete file feature is enabled 
function deleteObject() { 
    getS3Client()->deleteObject(array(
     'Bucket' => $_POST['bucket'], 
     'Key' => $_POST['key'] 
    )); 
} 

function signRequest() { 
    header('Content-Type: application/json'); 

    $responseBody = file_get_contents('php://input'); 
    $contentAsObject = json_decode($responseBody, true); 
    $jsonContent = json_encode($contentAsObject); 

    $headersStr = $contentAsObject["headers"]; 
    if ($headersStr) { 
     signRestRequest($headersStr); 
    } 
    else { 
     signPolicy($jsonContent); 
    } 
} 

function signRestRequest($headersStr) { 
    if (isValidRestRequest($headersStr)) { 
     $response = array('signature' => sign($headersStr)); 
     echo json_encode($response); 
    } 
    else { 
     echo json_encode(array("invalid" => true)); 
    } 
} 

function isValidRestRequest($headersStr) { 
    global $expectedBucket; 

    $pattern = "/\/$expectedBucket\/.+$/"; 
    preg_match($pattern, $headersStr, $matches); 

    return count($matches) > 0; 
} 

function signPolicy($policyStr) { 
    $policyObj = json_decode($policyStr, true); 

    if (isPolicyValid($policyObj)) { 
     $encodedPolicy = base64_encode($policyStr); 
     $response = array('policy' => $encodedPolicy, 'signature' => sign($encodedPolicy)); 
     echo json_encode($response); 
    } 
    else { 
     echo json_encode(array("invalid" => true)); 
    } 
} 

function isPolicyValid($policy) { 
    global $expectedMaxSize, $expectedBucket; 

    $conditions = $policy["conditions"]; 
    $bucket = null; 
    $parsedMaxSize = null; 

    for ($i = 0; $i < count($conditions); ++$i) { 
     $condition = $conditions[$i]; 

     if (isset($condition["bucket"])) { 
      $bucket = $condition["bucket"]; 
     } 
     else if (isset($condition[0]) && $condition[0] == "content-length-range") { 
      $parsedMaxSize = $condition[2]; 
     } 
    } 

    return $bucket == $expectedBucket && $parsedMaxSize == (string)$expectedMaxSize; 
} 

function sign($stringToSign) { 
    global $clientPrivateKey; 

    return base64_encode(hash_hmac(
      'sha1', 
      $stringToSign, 
      $clientPrivateKey, 
      true 
     )); 
} 

// This is not needed if you don't require a callback on upload success. 
function verifyFileInS3() { 
    global $expectedMaxSize; 

    $bucket = $_POST["bucket"]; 
    $key = $_POST["key"]; 

    // If utilizing CORS, we return a 200 response with the error message in the body 
    // to ensure Fine Uploader can parse the error message in IE9 and IE8, 
    // since XDomainRequest is used on those browsers for CORS requests. XDomainRequest 
    // does not allow access to the response body for non-success responses. 
    if (getObjectSize($bucket, $key) > $expectedMaxSize) { 
     // You can safely uncomment this next line if you are not depending on CORS 
     //header("HTTP/1.0 500 Internal Server Error"); 
     deleteObject(); 
     echo json_encode(array("error" => "File is too big!")); 
    } 
    else { 
     echo json_encode(array("tempLink" => getTempLink($bucket, $key))); 
    } 
} 
function testfunction(){ 
    alert('whatever'); 
} 
// Provide a time-bombed public link to the file. 
function getTempLink($bucket, $key) { 
    $client = getS3Client(); 
    $url = "{$bucket}/{$key}"; 
    $request = $client->get($url); 

    return $client->createPresignedUrl($request, '+15 minutes'); 
} 

function getObjectSize($bucket, $key) { 
    $objInfo = getS3Client()->headObject(array(
      'Bucket' => $bucket, 
      'Key' => $key 
     )); 
    return $objInfo['ContentLength']; 
} 
?> 

Мой HTML. Я использовал другой пример, что Марк имел на StackOverflow для этого теста, потому что в конце концов, я хочу, чтобы одновременно представить некоторые другие данные:

<!DOCTYPE html> 
<html> 
<head> 

    <title>test of fine uploader</title> 
    <meta charset="utf-8" /> 
    <meta name="viewport" content="width=device-width, initial-scale=1"> 


    <link href="fineuploader-3.8.0.css" rel="stylesheet"> 
    <style> 
    .button { 
     display: block; 
     height: 30px; 
     width: 100px; 
     border: 1px solid #000; 
    } 
    </style> 
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script> 
<script src="s3.jquery.fineuploader-3.8.0.js"></script> 
<script type="text/javascript" src="lenz_javascript4.js"></script> 

</head> 
<body> 

<!-- Generated Image Thumbnail --> 
<a href="#" id="thumbnail">view image</a> 

<form action="fineuploadertest.php" method="post" id="uploader"> 
<input type="text" name="textbox" value="Test data"> 
    <div id="manual-fine-uploader"></div> 
    <div id="triggerUpload" class="button" style="margin-top: 10px;">click here 
    </div> 
</form> 

</body> 
</html> 

Моя JavaScript:

$(document).ready(function() { 

    $("#triggerUpload").click(function() { 
     $("#manual-fine-uploader").fineUploaderS3('uploadStoredFiles'); 
    }); 

    function submitForm() { 
     if ($(this).fineUploader('getInProgress') == 0) { 
      var failedUploads = $(this).fineUploaderS3('getUploads', 
       { status: qq.status.UPLOAD_FAILED }); 
      if (failedUploads.length == 0) {  
       // do any other form processing here 
       $("#uploader").submit(); 
      } 
     } 
    }; 


    $("#manual-fine-uploader").fineUploaderS3({ 
     autoUpload: false, 
     debug: true, 

       request: { 

        endpoint: "http://my bucket name.s3.amazonaws.com", 

        accessKey: “I put my access key here” 
       }, 
       validation: { 
        allowedExtensions: ['jpeg', 'jpg', 'gif', 'png'], 
        sizeLimit: 15000000, 
        itemLimit: 3 
       }, 

       signature: { 

        endpoint: "s3demo.php" 
       }, 
      camera: { 
       ios: true 
      }, 
       iframeSupport: { 
        localBlankPagePath: "/success.html" 
       }, 
       uploadSuccess: { 
     endpoint: "s3demo.php?success" 

    } 
    }); 
}); 
+0

Похоже на то, что вы установили AWS SDK и/или его зависимости. Я делаю ставку каждый раз, когда запускается PHP-скрипт (т. Е. Каждый раз, когда он получает HTTP-запрос в этом случае), он пытается «потребовать» и «использовать» SDK в [строках 25 и 26] (https://github.com /Widen/fine-uploader-server/blob/master/php/s3/s3demo.php#L25). Можете ли вы просто прокомментировать эти строки и отключить функцию файла удаления, чтобы сузить проблему? –

+0

У меня возникали проблемы с другими установщиками PHP, но использование zip лучше всего для меня. У меня просто был каталог «aws» в той же папке, что и скрипт s3demo.php. –

+0

У меня на самом деле уже удалили файл.И до того, как я также прокомментировал строки 25 и 26, я получил эту ошибку в консоли (вынимая теги, чтобы она читалась здесь): [FineUploader 3.8.0] Получил следующий ответный элемент для загрузки AWS запрос успеха для id 0: Неустранимая ошибка: класс «S3Client» не найден в s3demo.php в строке 112. Итак, я решил, что должен расколоть строки 25 и 26, а затем я получил ошибки, показанные выше. –

ответ

4

Это звучит, как вы просто хотите, чтобы отразить поведение демонстрации S3 на FineUploader.com. Итак, у части, с которой вы, по-видимому, возникают проблемы, является часть демонстрации, которая позволяет вам просматривать/загружать загруженный файл. Я предполагаю, что вы не устанавливаете переменные окружения PARAM1 и PARAM2.Вы действительно должны взглянуть на то, как супер-глобальность работает в документации PHP. Этот код, как он есть, ожидает, что у вас будет переменная системной среды с именем PARAM1, которая содержит общедоступный AWS-ключ, связанный с пользователем IAM, который вы должны создать для своего сервера (а не вашего клиента). Переменная системной среды PARAM2 должна быть установлена ​​на секретный ключ для этого же пользователя. Вы можете либо установить эти переменные среды, либо установить связанные глобальные переменные и $serverPrivateKey на общедоступные и секретные ключи пользователя IAM на стороне сервера, соответственно.

Обратите внимание, что плохой выбор имени для системной переменной среды, связанные с AWS публикой сервера и секретным ключом (PARAM1 и PARAM2) связан с тем, что сервер для fineuploader.com S3 демо работает на AWS EC2 instance созданного от Amazon's Elastic Beanstalk service. Эластичный Beanstalk не предоставляет (по крайней мере, это явно не дает) способ назвать переменные системной среды через UI-интерфейс для использования PHP-приложений. Она называет их PARAM1, PARAM2 и т.д.

В $serverPublicKey и $serverPrivateKey переменные не должны быть одни и те же ключи, связанные с пользователем IAM, созданный для клиентской части задач. Вы должны создать другого пользователя IAM с разрешениями, подходящими для задач на стороне сервера. Например, если вы хотите поддерживать функцию файла удаления, вы хотели бы иметь пользователя IAM с разрешением «S3: DeleteObject». Этот пользователь должен быть ограничен задачами на стороне сервера только по соображениям безопасности.

В вашем случае пользователь IAM на стороне сервера должен иметь разрешение «S3: GetObject» на вашем ведре. Это разрешение требуется для получения объектов из вашего ведра. Самый безопасный подход заключается в предоставлении этого разрешения только для пользователя IAM на стороне сервера. Вероятно, вы спрашиваете: «Если мой клиентский пользователь не может читать объект из моего ведра, как разрешить загрузку файла на стороне клиента?» Ну, один из вариантов заключается в том, чтобы установить параметр acl в Fine Uploader в «общедоступный», а затем создать клиентскую часть URL с использованием этого соглашения: «http://mybucket.s3.amazonaws.com/objectkey». Это НЕ способ, которым работает демонстрация S3 на сайте fineuploader.com. Читайте дальше для подробностей ...

Я не хотел предоставлять пользователям неограниченный доступ к файлам, которые они загружали в ящик Fine3, поэтому я оставил acl «частным» (значение по умолчанию), я только дал свой пользователь IAM на стороне сервера. «S3: GetObject» разрешает вещественный загрузчик S3, и у меня есть сервер, который возвращает «связанный с бомбой» подписанный URL-адрес связанного объекта в ведре. URL-адрес, возвращаемый сервером, содержит параметр срока действия, который позволяет использовать его только 15 минут. Любые попытки изменить этот параметр истечения в строке запроса аннулируют подпись, и запрос будет терпеть неудачу. Функция getTempLink в примере PHP будет генерировать подписанный по времени URL-адрес, который возвращается в ответе POST-запроса FineBacker uploadSucess.endpoint. Вы можете получить доступ к этому значению, внося свой вклад complete event handler. Параметр объекта responseJSON, переданный в ваш обратный вызов, будет содержать свойство tempLink, которое будет содержать подписанный URL-адрес. Затем вы можете создать привязку с атрибутом src, установленным для значения этого свойства.

+1

Спасибо, я думал, что это переменные PARAM1 и PARAM2, но я не знал, какими они должны быть. Теперь я понимаю, благодаря вашему очень четкому объяснению. –

+0

Рад, что я мог помочь. Чтобы помочь будущим интеграторам, @MarkFeltner и я, вероятно, добавим больше комментариев к примерам на стороне сервера, связанным с этими переменными, чтобы было ясно, каковы их роли. –

+0

Прочитав это, я наконец понял, что вам нужно иметь набор из двух секретных ключей. Одна учетная запись (серверные ключи) и один IAM (клиентские ключи). Теперь я могу просмотреть файлы после загрузки, так что спасибо! –

 Смежные вопросы

  • Нет связанных вопросов^_^