Estoy desarrollando un sitio web en HTML, javascript & jQuery. Quiero subir imágenes al servidor de amazon s3 en una petición ajax. No hay tal SDK para integrar s3 en Javascript. Un SDK para PHP está disponible, pero no es útil para mí. ¿Alguien puede proporcionar la solución a esto en javascript?

  • usted realmente debe cambiar el aceptado la respuesta a esta pregunta ya que ahora es posible.

5 Comentarios

  1. 121

    Consiguió Amazon S3 & CORS de trabajo en js y html5 utilizando XMLHTTPObject basado en este artículo artículo.

    1: CORS sólo funciona a partir de una dirección URL correcta «http://localhost«. (archivo///xyz se te vuelva loco)

    2 : asegúrese de que usted tiene la POLÍTICA y Secreto compilado correctamente – aquí es mi política y este es el enlace que usted puede conseguir el proyecto para comenzar con Firma y Política — no publicar este JS con su Secreto NUNCA!

    POLICY_JSON = { "expiration": "2020-12-01T12:00:00.000Z",
                "conditions": [
                {"bucket": this.get('bucket')},
                ["starts-with", "$key", ""],
                {"acl": this.get('acl')},                           
                ["starts-with", "$Content-Type", ""],
                ["content-length-range", 0, 524288000]
                ]
              };
    
    
        var secret = this.get('AWSSecretKeyId');
        var policyBase64 = Base64.encode(JSON.stringify(POLICY_JSON));
        console.log ( policyBase64 )
    
        var signature = b64_hmac_sha1(secret, policyBase64);
        b64_hmac_sha1(secret, policyBase64);
        console.log( signature);

    Aquí está el código JS

    function uploadFile() {
    
        var file = document.getElementById('file').files[0];
        var fd = new FormData();
    
        var key = "events/" + (new Date).getTime() + '-' + file.name;
    
        fd.append('key', key);
        fd.append('acl', 'public-read'); 
        fd.append('Content-Type', file.type);      
        fd.append('AWSAccessKeyId', 'YOUR ACCESS KEY');
        fd.append('policy', 'YOUR POLICY')
        fd.append('signature','YOUR SIGNATURE');
    
        fd.append("file",file);
    
        var xhr = getXMLHTTPObject();
    
        xhr.upload.addEventListener("progress", uploadProgress, false);
        xhr.addEventListener("load", uploadComplete, false);
        xhr.addEventListener("error", uploadFailed, false);
        xhr.addEventListener("abort", uploadCanceled, false);
    
        xhr.open('POST', 'https://<yourbucket>.s3.amazonaws.com/', true); //MUST BE LAST LINE BEFORE YOU SEND 
    
        xhr.send(fd);
      }

    Funciones auxiliares

    function uploadProgress(evt) {
        if (evt.lengthComputable) {
          var percentComplete = Math.round(evt.loaded * 100 / evt.total);
          document.getElementById('progressNumber').innerHTML = percentComplete.toString() + '%';
        }
        else {
          document.getElementById('progressNumber').innerHTML = 'unable to compute';
        }
      }
    
      function uploadComplete(evt) {
        /* This event is raised when the server send back a response */
        alert("Done - " + evt.target.responseText );
      }
    
      function uploadFailed(evt) {
        alert("There was an error attempting to upload the file." + evt);
      }
    
      function uploadCanceled(evt) {
        alert("The upload has been canceled by the user or the browser dropped the connection.");
      }

    A continuación, el Formulario HTML

     <form id="form1" enctype="multipart/form-data" method="post">
    <div class="row">
      <label for="file">Select a File to Upload</label><br />
      <input type="file" name="file" id="file" onchange="fileSelected()"/>
    </div>
    <div id="fileName"></div>
    <div id="fileSize"></div>
    <div id="fileType"></div>
    <div class="row">
      <input type="button" onclick="uploadFile()" value="Upload" />
    </div>
    <div id="progressNumber"></div>

    Feliz CORS-ing!

    • Hola gente. Esto parece ser exactamente lo que estoy buscando para subir a mi S3. Sin embargo, estoy perplejo en la primera parte (irónicamente, el resto parece straight-forward). Soy un total de newb cuando se trata de S3 y para ser honesto yo no sé qué hacer con el POLICY_JSON código. En resumen: ¿dónde pongo esto?
    • Acabo de encontrar este artículo que explica la anatomía de AWS formulario de carga en detalle: aws.amazon.com/articles/1434
    • Qué archivo que están utilizando para definir Base64?
    • Gracias por publicar esto, me ayudó un montón!
    • De acuerdo. me tomó un tiempo para llegar hay que buscar en google, pero en la última!
    • Accesorios para una limpieza, biblioteca independiente de la respuesta!
    • Mi evt.target.responseText es siempre en blanco, ¿sabes por qué? Además, ¿cómo puedo obtener la url de los archivos subidos? gracias!
    • ¿cómo aplicar este si estoy usando credenciales temporales, aquellos que tienen un token de sesión para incluir.?
    • Este post podría mejorarse si el autor podría considerar la posibilidad de explicar lo que estamos haciendo en el primer ejemplo de código. El vínculo que se hace referencia tiene un ejemplo similar en Ruby, Java y Python. El problema más grande es, que el autor omitió decir que las bibliotecas son utilizadas para Base64 y Crypto. (nodo estándar de criptografía debería funcionar)
    • Jim – es cierto – yo solía Base64 para conseguir que esto funcione –
    • usted necesita para obtener las variables que se rellena a partir de su política de AWS archivo. Conseguir que este proyecto se ejecuta github.com/tweetegy/save_image_directly_to_s3_using_backbone para que se entienda, donde las variables que se vienen.
    • Sería estupendo si alguien tiene esto convierte a angular’!
    • esta solución no requiere de un servidor del lado de la lógica. Por favor revisar el código y la metodología anterior antes de llegar a su conclusión.
    • Estoy confundido – ya sea de publicar su AWS secreto (no recomendado) o de firmar el formulario del lado del servidor? Que estás defendiendo, o he perdido de algo?
    • Utilizar únicamente la primera parte del ejemplo, para crear su «firma» en su ambiente privado..que nunca se haya publicar el código. La primera parte del post (obtención de la firma) es super privado y la u nunca cargar en cualquier lugar. Después de conseguir que el programa de instalación usa esa «firma» de esta línea (var firma = b64_hmac_sha1(secreto, policyBase64);) públicamente en conjunción con su AWSAccessKeyId, la Política — Siguiendo estos pasos, usted nunca tendrá que compartir su AWS Secreto.
    • OK, no había considerado que puede generar que la parte offline. Es importante señalar, sin embargo, que a menudo necesita para regenerar la firma de forma dinámica, por ejemplo, cuando la fecha de vencimiento de los cambios. Pero antes de generación podría ser útil en algunos casos, sí.
    • ¿De dónde b64_hmac_sha1 vienen?
    • parte de la base de la biblioteca – github.com/tweetegy/save_image_directly_to_s3_using_backbone/…
    • var xhr = getXMLHTTPObject(); debe ser var xhr = new XMLHttpRequest(); buen guión, lástima que todavía necesitan el uso de mierda iframes para IE8 y 9
    • fileSelected no está implementado AFAICT.
    • Si este es un script para un sitio público, te recomiendo generar un temporal firma del/la política en el lado del servidor para cada nueva carga, que, a continuación, vence en algún momento en el futuro. Consulte este artículo
    • Hola Gracias, pero me estoy enfrentando este problema en firefox RequestTimeout Su conexión de socket con el servidor no se ha leído o escrito dentro del período de tiempo de espera. Conexiones inactivas será cerrado y el archivo es no cargar en S3.Puede usted por favor me ayuden en como puedo solucionar este problema.Gracias
    • También he abierto un tema en GitHub por favor, eche un vistazo a este Agradecimiento va a ser realmente útil. github.com/aws/aws-sdk-php/issues/1332
    • por favor, echa para atrás js compatibilidad en mi solución, ya que ahora es de unos 5 años de edad. Algunas de las funciones centrales de llamadas podría haber cambiado.
    • Gracias @fino y puede usted por favor me guía un poco cómo puedo comprobar hacia atrás js de compatibilidad.
    • ¿Qué pasa si no uso codificado claves de acceso y claves secretas? Qué pasa si usted está utilizando las Funciones de IAM (que no tienen Acceso/Claves Secretas? ¿Qué usar en el lugar de ellos?

  2. 7

    Amazon sólo permite Cross-Origin Resource Sharing, en teoría, permite a los usuarios a subir a S3 directamente, sin utilizar el servidor (y PHP) como un proxy.

    Heres docs -> http://docs.amazonwebservices.com/AmazonS3/latest/dev/cors.html

    Hacen un gran trabajo de decirle a usted cómo habilitarlo en un S3, pero iv encontró ninguna javascript ejemplos de cómo obtener los datos desde el cliente al cubo.

    Primera persona en publicar CORS.js es una leyenda xD

  3. 3

    Usted puede hacer esto mediante la AWS S3 Cognito probar este enlace aquí :

    http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/browser-examples.html#Amazon_S3

    También probar este código

    Sólo cambiar la Región, IdentityPoolId y Su cubo nombre

    <!DOCTYPE html>
    <html>
    <head>
    <title>AWS S3 File Upload</title>
    <script src="https://sdk.amazonaws.com/js/aws-sdk-2.1.12.min.js"></script>
    </head>
    <body>
    <input type="file" id="file-chooser" />
    <button id="upload-button">Upload to S3</button>
    <div id="results"></div>
    <script type="text/javascript">
    AWS.config.region = 'your-region'; //1. Enter your region
    AWS.config.credentials = new AWS.CognitoIdentityCredentials({
    IdentityPoolId: 'your-IdentityPoolId' //2. Enter your identity pool
    });
    AWS.config.credentials.get(function(err) {
    if (err) alert(err);
    console.log(AWS.config.credentials);
    });
    var bucketName = 'your-bucket'; //Enter your bucket name
    var bucket = new AWS.S3({
    params: {
    Bucket: bucketName
    }
    });
    var fileChooser = document.getElementById('file-chooser');
    var button = document.getElementById('upload-button');
    var results = document.getElementById('results');
    button.addEventListener('click', function() {
    var file = fileChooser.files[0];
    if (file) {
    results.innerHTML = '';
    var objKey = 'testing/' + file.name;
    var params = {
    Key: objKey,
    ContentType: file.type,
    Body: file,
    ACL: 'public-read'
    };
    bucket.putObject(params, function(err, data) {
    if (err) {
    results.innerHTML = 'ERROR: ' + err;
    } else {
    listObjs(); //this function will list all the files which has been uploaded
    //here you can also add your code to update your database(MySQL, firebase whatever you are using)
    }
    });
    } else {
    results.innerHTML = 'Nothing to upload.';
    }
    }, false);
    function listObjs() {
    var prefix = 'testing';
    bucket.listObjects({
    Prefix: prefix
    }, function(err, data) {
    if (err) {
    results.innerHTML = 'ERROR: ' + err;
    } else {
    var objKeys = "";
    data.Contents.forEach(function(obj) {
    objKeys += obj.Key + "<br>";
    });
    results.innerHTML = objKeys;
    }
    });
    }
    </script>
    </body>
    </html>

    Si es necesario se puede utilizar Enlace a github

    Espero que ayude a los demás 🙂

    • Yo estoy haciendo un 403
  4. 0

    Para la autenticación parte,

    Nada de código php, no hay ningún servidor, no hay grandes el código JS excepto los de abajo;

    puede utilizar AWS Cognito IdentityPoolId como credencial, menos código
    pero que son necesarios para crear AWS Cognito IdetityPool y adjuntar la política, simplemente s3 acceso de escritura.

     var IdentityPoolId = 'us-east-1:1...........'; 
    AWS.config.update({ 
    credenciales: nueva AWS.CognitoIdentityCredentials({ 
    IdentityPoolId: IdentityPoolId 
    }) 
    }); 
    
    • ¿cómo puedo obtener el IdentityPoolId ¿puede por favor explicar un poco Gracias.
    • Y simplemente permitir que todo el mundo que huele su Cognito token de un simple analizador de tráfico de red para obtener la autorización para el volcado de los archivos en su S3 gratis continuamente sin su control. Eso es el costo de «no hay código que no hay ningún servidor, sin grandes JS»
    • usted debe olvidado no hay cosa como https
    • Un Cognito token es otro token JWT, supongo que si subes a un servidor cuyo mecanismo de seguridad es el mismo será tan propensa al analizador de tráfico como Cognito. Saltarse el servidor para un gran ancho de banda intensivo de tareas como subir una imagen binaria para s3 tiene sus ventajas y sus inconvenientes. En general JWT tokens no debería ser de larga duración, CORS ajustes en el S3 debe ser sensible y no ‘*’ en todo, Lambda post gancho desencadenantes pueden ser el programa de instalación en el S3 para validar cada carga son cosas que se pueden hacer para prevenir el uso no autorizado de las subidas.

Dejar respuesta

Please enter your comment!
Please enter your name here