Comment créer un raccourcisseur d'URL sans serveur avec AWS Lambda et S3

Utilisation de graphiques de SAP Scenes Pack

Tout au long de cet article, nous allons créer un raccourcisseur d’URL sans serveur à l’aide d’Amazon Web Services (AWS) Lambda et S3. Bien que vous n’ayez besoin d’aucune expérience préalable d’AWS, je suppose connaître un peu ES6 JavaScript et Node.js.

Ironiquement, les URL qui seront générées à partir de notre raccourcisseur d’URL seront souvent plus longues que les URL vers lesquelles elles sont redirigées, car nous utilisons l’adresse par défaut du site Web du compartiment S3. Vers la fin du post, je vais expliquer comment vous pouvez ajouter un domaine personnalisé pour contourner cette limitation.

Voir la démo

Voir le code sur Github

Il est relativement facile de démarrer avec AWS et pourtant, il y a clairement une complexité perçue. Le nombre de services disponibles peut être décourageant, car nombre d'entre eux se chevauchent dans leurs fonctionnalités. AWS Management Console, lent et peu intuitif, ne résout pas le problème, pas plus que la documentation en ligne très textuelle. Mais tout au long de ce post, j'espère démontrer que la meilleure façon d'adopter les services AWS est d'utiliser une approche incrémentielle et que vous pouvez commencer en n'utilisant qu'une poignée de services.

Nous allons utiliser Serverless Framework pour interagir avec AWS. Il n’est donc pas nécessaire de vous connecter à AWS Management Console. Serverless Framework fournit une abstraction sur AWS et permet de définir la structure de projet et les paramètres par défaut sensibles. Si vous voulez en savoir plus avant de commencer, vous devriez lire leur documentation.

Architecture

Avant de vous lancer dans un développement, examinons d’abord les services AWS que nous allons utiliser pour créer notre raccourcisseur d’URL.

Pour héberger notre site Web, nous allons utiliser le service de stockage de fichiers Amazon S3. Nous allons configurer notre compartiment S3, qui peut être considéré comme un dossier de niveau supérieur, pour servir un site Web statique. Le site Web comprendra du contenu statique et des scripts côté client. Il n’existe aucune possibilité d’exécuter du code côté serveur (PHP, Ruby ou Java, par exemple), mais cela convient à notre cas d’utilisation.

Nous allons également utiliser une fonctionnalité peu connue de S3 qui vous permet de configurer le transfert d'objets dans des compartiments S3 en ajoutant simplement une valeur Website-Redirect-Location aux métadonnées de l'objet. Si vous définissez cette option sur une URL, les navigateurs seront redirigés via une réponse HTTP 301 et l'en-tête d'emplacement.

L’URL d’un objet S3 est composée de l’adresse du compartiment S3 suivie du nom de l’objet.

http: // [nom du compartiment] .s3-website-eu-west-1.amazonaws.com / [nom de l'objet]

Voici un exemple de format d'un objet de compartiment S3 pour la région eu-west-1.

http://serverless-url-shortener.s3-website-eu-west-1.amazonaws.com/6GpLcdl

Ce nom d'objet «6GpLcdl» à la fin de l'URL dans l'exemple ci-dessus devient le shortcode de nos URL raccourcies. En utilisant cette fonctionnalité, nous obtenons une redirection d’URL native ainsi que des capacités de stockage. Nous n’avons pas besoin d’une base de données pour stocker les détails de chaque shortcode pointant vers quelle URL car cette information sera stockée avec l’objet lui-même.

Nous allons créer une fonction Lambda pour enregistrer ces objets S3 avec les métadonnées appropriées dans notre compartiment S3.

Vous pouvez également utiliser le côté client du kit SDK AWS dans le navigateur pour enregistrer les objets. Mais il est préférable d’extraire cette fonctionnalité dans un service séparé. Il offre l'avantage de ne pas avoir à s'inquiéter de la divulgation des informations d'identification de sécurité et est plus extensible à l'avenir. Nous allons mapper la fonction Lambda sur un noeud final de la passerelle API afin qu'elle soit accessible via un appel d'API.

Commencer

Rendez-vous sur les documents Serverless Framework et parcourez leur guide de démarrage rapide. Dans le cadre du processus de configuration, vous devrez installer l'AWS CLI et configurer vos informations d'identification AWS.

Commencez par créer un fichier package.json à la racine du projet.

{
  "name": "serverless-url-shortener",
  "scripts": {},
  "dépendances": {}
}

Nous savons que nous devrons utiliser le kit SDK AWS. Par conséquent, installez-le à partir de NPM maintenant en entrant la commande suivante.

npm installer aws-sdk --save

Créez maintenant un fichier config.json également à la racine du projet. Nous allons utiliser cela pour stocker des options utilisateur personnalisables au format JSON.

Ajoutez les clés suivantes avec les valeurs appropriées à votre configuration.

  • BUCKET - nom que vous souhaitez utiliser pour votre compartiment S3. Cela fera partie de l'URL courte si vous choisissez de ne pas ajouter de domaine personnalisé. Il doit être propre à la région dans laquelle vous vous déployez. Ne choisissez donc pas quelque chose de trop générique. Mais ne vous inquiétez pas, si le nom du compartiment que vous avez choisi est déjà utilisé, vous serez averti par le biais de la CLI Serverless lors du déploiement.
  • REGION - la région AWS dans laquelle vous souhaitez déployer. Il est préférable de choisir la région la plus proche de vos utilisateurs pour des raisons de performances. Si vous suivez simplement le tutoriel, je vais utiliser eu-west-1.
  • STAGE - la scène où se déployer. En général, vous disposez d’un environnement de transfert qui reproduit la même configuration que votre environnement de production. Cela vous permet de tester les versions logicielles de manière non destructive. Comme il s’agit d’un tutoriel, je vais me déployer au stade du développement.

Votre fichier config.json devrait ressembler au suivant une fois terminé.

{
  "BUCKET": "votre-nom de seau",
  "REGION": "eu-west-1",
  "STAGE": "dev",
}

Ensuite, créez un autre fichier à la racine du projet, serverless.yml. Ceci maintiendra notre configuration Framework sans serveur au format YAML.

Dans ce fichier, nous commencerons par définir notre environnement. Remarquez comment nous pouvons référencer des variables stockées précédemment dans config.json.

service: serveurless-url-shortener

fournisseur:
  nom: aws
  runtime: nodejs6.10
  stage: $ {fichier (config.json): STAGE}
  région: $ {fichier (config.json): REGION}
  iamRoleStatements:
    - Effet: permettre
      Action:
        - s3: PutObject
      Ressource: "arn: aws: s3 ::: $ {fichier (config.json): BUCKET} / *"

La section iamRoleStatements fait référence à Gestion des identités et des accès, utilisée pour configurer les autorisations Lambda. Nous donnons ici à Lambda un accès en écriture à notre compartiment S3.

Pour sauvegarder des objets, nous avons besoin d'une autorisation pour exécuter l'action s3: PutObject. D'autres autorisations peuvent être ajoutées ici si elles sont requises par votre projet. Reportez-vous à la documentation S3 pour connaître les autres actions disponibles.

La valeur de la ressource est définie sur le nom de ressource Amazon du compartiment S3, utilisé pour identifier de manière unique une ressource AWS particulière. Le format de cet identificateur dépend du service AWS auquel il est fait référence, mais ils ont généralement le format suivant.

arn: partition: service: région: identifiant de compte: ressource

Sous fournisseur ajouter notre configuration des fonctions.

les fonctions:
  le magasin:
    gestionnaire: api.handle
    événements:
      - http:
          chemin: /
          méthode: post
          cors: true

Ici, nous définissons la configuration de l’API et mappons notre Lambda à un événement HTTP POST à ​​l’URL de base de l’API. Un gestionnaire avec la valeur api.handle fait référence à une fonction nommée handle exportée à partir de api.js (nous n’avons pas besoin de l’extension de fichier js car précédemment, dans le fichier serverless.yml, nous définissions le moteur à nodejs6.10).

Lambda est basé sur les événements et les fonctions ne sont donc exécutées que sur la base de déclencheurs prédéfinis. Nous avons défini ici un événement HTTP, mais il aurait également pu s'agir d'un événement déclenché par une table DynamoDB ou une file d'attente SQS.

Ensuite, dans serverless.yml, nous définissons les ressources AWS à instancier pour nous lors du déploiement à l'aide de CloudFormation. Il est à noter que vous ne devez pas nécessairement configurer les ressources de cette façon, vous pouvez également les créer à l'aide de AWS Management Console. Si les autorisations d’accès correctes sont en place, peu importe la façon dont les ressources sont créées. Mais en définissant les services requis dans serverless.yml, vous définissez votre "infrastructure en tant que code" et vous obtenez de nombreux avantages.

«L’infrastructure en tant que code est l’approche permettant de définir une infrastructure informatique et réseau par le biais d’un code source pouvant être traité comme tout logiciel. Ce code peut être conservé dans le contrôle de source pour permettre une auditabilité et des structures ReproducibleBuild, soumises aux pratiques de test, et à la discipline complète de ContinuousDelivery. ”
- Martin Fowler

Allez-y et ajoutez la configuration des ressources.

Ressources:
  Ressources:
    ServerlessRedirectS3Bucket:
      Type: AWS :: S3 :: Bucket
      Propriétés:
        BucketName: $ {fichier (config.json): BUCKET}
        AccessControl: PublicRead
        WebsiteConfiguration:
          IndexDocument: index.html
    ServerlessRedirectS3BucketPolicy:
      Type: AWS :: S3 :: BucketPolicy
      Propriétés:
        Bucket: $ {fichier (config.json): BUCKET}
        PolicyDocument:
          Déclaration:
          - Action:
            - s3: GetObject
            Effet: permettre
            Ressource:
            - arn: aws: s3 ::: $ {fichier (config.json): BUCKET} / *
            Principal: "*"

Nous demandons une ressource de compartiment S3 configurée pour utiliser l'hébergement de site statique avec index.html comme document racine. Les seaux S3 sont pour une bonne raison privés par défaut et nous devons donc créer une stratégie de seau S3 permettant un accès public à celle-ci. Sans cette politique, les visiteurs du site Web afficheraient plutôt un message d'erreur non authentifié.

Construire l'API

Notre fonction Lambda est responsable de quatre tâches.

  1. Saisir l’URL à raccourcir à partir de la soumission du formulaire de l’utilisateur.
  2. Générer un shortcode unique pour l'URL.
  3. Enregistrement de l'objet de redirection approprié dans S3.
  4. Renvoyer le chemin de l'objet au client.

Créer le gestionnaire

Créez un nouveau fichier nommé api.js et exportez une fonction de flèche nommée handle, qui prend trois arguments: événement, contexte et rappel. Celles-ci seront fournies par AWS lorsque le gestionnaire sera appelé. Ce fichier est un script Node.js. Pour exporter la fonction de flèche, vous devez l’ajouter à module.exports.

module.exports.handle = (événement, contexte, rappel) => {
}

Ce gestionnaire sera invoqué lorsqu'une demande HTTP POST est adressée à notre point de terminaison. Pour renvoyer une réponse de l'API, nous devons utiliser la fonction de rappel fournie fournie en tant que troisième argument de la fonction de flèche. Il s’agit d’un premier rappel sur erreur qui prend deux arguments. Si la demande est complétée avec succès, null doit être transmis comme premier argument. L'objet de réponse transmis en tant que deuxième argument détermine le type de réponse à renvoyer à l'utilisateur. Générer une réponse est aussi simple que de fournir un statusCode et un corps, comme indiqué dans l'exemple ci-dessous.

réponse constante = {
  statusCode: 201,
  body: JSON.stringify ({"shortUrl": "http://example.com"})
}
rappel (null, réponse)

L’objet de contexte transmis en tant que deuxième argument au gestionnaire contient des informations d’exécution auxquelles nous n’avons pas besoin d’accéder à ce didacticiel. Nous devons cependant utiliser l'événement transmis comme premier argument car il contient la soumission du formulaire avec l'URL à raccourcir.

Analyser la demande

Vous trouverez ci-dessous un exemple d'événement API Gateway qui sera transmis à notre gestionnaire lorsqu'un utilisateur soumettra un formulaire. Au fur et à mesure que nous construisons notre raccourci d’URL en tant qu’application à une seule page, nous soumettrons le formulaire à l’aide de JavaScript. Par conséquent, le type de contenu sera application / json plutôt que application / x-www-form-urlencoded.

{
   Ressource:'/',
   chemin:'/',
   httpMethod: 'POST',
   en-têtes: {
      Acceptez:'*/*',
      'Accept-Encoding': 'gzip, deflate',
      'cache-control': 'no-cache',
      'CloudFront-Forwarded-Proto': 'https',
      'CloudFront-Is-Desktop-Viewer': 'true',
      'CloudFront-Is-Mobile-Viewer': 'false',
      'CloudFront-Is-SmartTV-Viewer': 'false',
      'CloudFront-Is-Tablet-Viewer': 'false',
      'CloudFront-Viewer-Country': 'GB',
      'content-type': 'application / json',
      Hôte:'',
      'Agent utilisateur':'',
      'X-Amz-Cf-Id': '',
      'X-Amzn-Trace-Id': '',
      'X-Forwarded-For': '',
      'X-Forwarded-Port': '443',
      'X-Forwarded-Proto': 'https'
   },
   queryStringParameters: null,
   pathParameters: {},
   stageVariables: null,
   requestContext: {
      chemin: '/ dev',
      identifiant de compte:'',
      resourceId: '',
      étape: 'dev',
      requestId: '',
      identité:{
         cognitoIdentityPoolId: null,
         accountId: null,
         cognitoIdentityId: null,
         appelant: null,
         clé API:'',
         sourceIp: '',
         accessKey: null,
         cognitoAuthenticationType: null,
         cognitoAuthenticationProvider: null,
         userArn: null,
         agent utilisateur:'',
         utilisateur: null
      },
      resourcePath: '/',
      httpMethod: 'POST',
      apiId: ''
   },
   body: '{"url": "http://example.com"}',
   isBase64Encoded: false
}

Nous avons seulement besoin de la soumission du formulaire de l'événement, que nous pouvons obtenir en consultant le corps de la demande. Le corps de la demande est stocké sous la forme d'un objet JavaScript codifié que nous pouvons récupérer à l'intérieur de notre gestionnaire à l'aide de JSON.parse (). En tirant parti de l’évaluation du court-circuit JavaScript, nous pouvons définir la valeur par défaut d’une chaîne vide pour les cas où une URL n’a pas été envoyée dans le cadre de la soumission du formulaire. Cela nous permet de traiter les instances dans lesquelles l'URL est manquante et où l'URL est une chaîne vide également.

module.exports.handle = (événement, contexte, rappel) => {
  let longUrl = JSON.parse (event.body) .url || ''
}

Valider l'URL

Ajoutons une validation de base pour vérifier que l’URL fournie a l'air légitime. Plusieurs approches peuvent être adoptées pour atteindre cet objectif. Mais pour les besoins de ce tutoriel, nous allons rester simples et utiliser le module d’URL intégré Node.js. Nous allons construire notre validation pour renvoyer une promesse résolue sur une URL valide et renvoyer une promesse refusée sur une URL non valide. Les promesses en JavaScript peuvent être chaînées de manière séquentielle afin que la résolution d'une promesse soit transmise au gestionnaire de succès de la suivante. Nous allons utiliser cet attribut de promesse pour structurer notre gestionnaire. Écrivons la fonction de validation en utilisant des promesses.

const url = require ('url')
fonction validate (longUrl) {
  if (longUrl === '') {
    retourne Promise.reject ({
      statusCode: 400,
      message: 'URL is required'
    })
  }
let parsedUrl = url.parse (longUrl)
  if (parsedUrl.protocol === null || parsedUrl.host === null) {
    retourne Promise.reject ({
      statusCode: 400,
      message: 'l'URL n'est pas valide'
    })
  }
retourne Promise.resolve (longUrl)
}

Dans notre fonction de validation, nous vérifions d’abord que l’URL n’est pas définie sur une chaîne vide. Si c'est le cas, nous retournons une promesse refusée. Notez que la valeur rejetée est un objet contenant un code d’état et un message. Nous utiliserons cela plus tard pour créer une réponse d'API appropriée. L'appel de l'analyse sur le module d'URL Node.js renvoie un objet URL contenant des informations pouvant être extraites de l'URL transmise sous forme d'argument de chaîne. Dans le cadre de notre validation d’URL de base, nous vérifions simplement si un protocole (par exemple, «http») et un hôte (comme «exemple.com») peuvent être extraits. Si l'une de ces valeurs est null sur l'objet URL renvoyé, nous supposons que l'URL n'est pas valide. Si l'URL est valide, nous le renvoyons dans le cadre d'une promesse résolue.

Renvoyer une réponse

Après avoir récupéré l'URL de la demande, nous appelons valider et pour chaque étape de gestionnaire supplémentaire requise, nous renverrons une nouvelle promesse dans le gestionnaire de réussite de la promesse précédente. Le dernier gestionnaire de réussite est chargé de renvoyer une réponse de l’API via l’argument de rappel du gestionnaire. Il sera invoqué pour les réponses d'erreur de l'API générées à partir de promesses rejetées ainsi que pour les réponses d'API réussies.

module.exports.handle = (événement, contexte, rappel) => {
  let longUrl = JSON.parse (event.body) .url || ''
  valider (longUrl)
    .then (function (path) {
      let response = buildResponse (200, 'success', path)
      retourne Promise.resolve (réponse)
    })
    .catch (function (err) {
      let response = buildResponse (err.statusCode, err.message)
      retourne Promise.resolve (réponse)
    })
    .then (fonction (réponse) {
      rappel (null, réponse)
    })
}
fonction buildResponse (statusCode, message, path = false) {
  let body = {message}
  if (chemin) corps ['chemin'] = chemin
  
  revenir {
    en-têtes: {
      'Access-Control-Allow-Origin': '*'
    },
    statusCode: statusCode,
    body: JSON.stringify (body)
  }
}

Générer un shortcode d'URL

L'API doit pouvoir générer des codes de fonction d'URL uniques, qui sont représentés sous la forme de noms de fichiers dans le compartiment S3. Comme un shortcode n’est qu’un nom de fichier, sa composition est très flexible. Pour notre code abrégé, nous utiliserons une chaîne alphanumérique à 7 chiffres composée à la fois de lettres majuscules et minuscules. Cela correspond à 62 combinaisons possibles pour chaque caractère. Nous allons utiliser la récursivité pour construire le shortcode en sélectionnant un caractère à la fois jusqu'à ce que sept soient sélectionnés.

function generatePath (path = '') {
  let characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
  let position = Math.floor (Math.random () * characters.length)
  let character = characters.charAt (position)
if (path.length === 7) {
  chemin de retour
}
return generatePath (chemin d'accès + caractère)
}

Alors que les chances de générer aléatoirement le même shortcode sont minces (il y a en fait une chance sur 000000000000000000000080803365516), nous devons vérifier si le shortcode généré est déjà utilisé, ce que nous pouvons faire à l'aide du kit SDK AWS. Il existe une méthode headObject sur le service S3 qui charge les métadonnées d’un objet. Nous pouvons l’utiliser pour vérifier si un objet portant le même nom existe déjà comme si aucun objet n’était trouvé, une promesse portant le code NotFound est rejetée. Cette promesse refusée indique que le shortcode est gratuit et peut être utilisé. L'appel de headObject est plus performant que de vérifier si l'objet existe via getObject, qui charge l'intégralité de l'objet.

const AWS = require ('aws-sdk')
const S3 = new AWS.S3 ()
fonction isPathFree (path) {
  retourne S3.headObject (buildRedirect (chemin)). promise ()
    .then (() => Promise.resolve (false))
    .catch (function (err) {
      if (err.code == 'NotFound') {
        retourne Promise.resolve (true)
      } autre {
        retourne Promise.reject (err)
      }
    })
}
fonction buildRedirect (chemin, longUrl = false) {
  laisser rediriger = {
    'Bucket': config.BUCKET,
    'Clé': chemin
  }
si (longUrl) {
    redirect ['WebsiteRedirectLocation'] = longUrl
  }
renvoyer la redirection
}

Nous pouvons utiliser isPathFree pour rechercher de manière récursive un chemin d'objet unique.

fonction getPath () {
  retourne une nouvelle promesse (fonction (résoudre, rejeter) {
    let path = generatePath ()
    isPathFree (chemin)
      .then (function (isFree) {
        le retour est-il gratuit? resolver (chemin): resolver (getPath ())
      })
  })
}

Profitant de la possibilité de chaîner les promesses, nous retournons une nouvelle invocation de getPath si isPathFree renvoie false.

Pour enregistrer un objet après la découverte d'un shortcode unique, il suffit d'appeler la méthode putObject sur le service AWS SDK S3. Enveloppons cela dans une fonction qui résout le shortcode si l’appel de la méthode putObject a réussi et renvoie un objet error pour générer une réponse d’API s’il ne l’a pas été.

fonction saveRedirect (redirection) {
  retourne S3.putObject (redirect) .promise ()
    .then (() => Promise.resolve (redirect ['Key']]))
    .catch (() => Promise.reject ({
      statusCode: 500,
      message: 'Erreur lors de l'enregistrement de la redirection'
  })
}

En utilisant les fonctions ci-dessus, nous pouvons ajouter deux nouveaux gestionnaires de succès de promesse pour finaliser notre point de terminaison API. Nous devons renvoyer getPath du premier gestionnaire de succès de promesse qui résoudra un shortcode d'URL unique. Le renvoi de saveRedirect avec un objet de redirection créé à l'aide de ce shortcode unique dans le deuxième gestionnaire de succès enregistrera l'objet dans le compartiment S3. Le chemin de cet objet peut ensuite être renvoyé au client dans le cadre d’une réponse de l’API. Notre gestionnaire devrait maintenant être complet.

module.exports.handle = (événement, contexte, rappel) => {
  let longUrl = JSON.parse (event.body) .url || ''
  valider (longUrl)
    .then (function () {
      retourne getPath ()
    })
    .then (function (path) {
      let redirect = buildRedirect (path, longUrl)
      retourne saveRedirect (redirection)
    })
    .then (function (path) {
      let response = buildResponse (200, 'success', path)
      retourne Promise.resolve (réponse)
    })
    .catch (function (err) {
      let response = buildResponse (err.statusCode, err.message)
      retourne Promise.resolve (réponse)
    })
    .then (fonction (réponse) {
      rappel (null, réponse)
    })
}

Déployer l'API

Exécutez le déploiement sans serveur dans votre terminal pour déployer l'API sur AWS. Cela va configurer notre compartiment S3 et renvoyer l'URL du noeud final. Conservez l'URL du terminal client à portée de main, car nous en aurons besoin ultérieurement.

Serverless: service de packaging ...
Serverless: Exclure les dépendances de développement ...
Serverless: Téléchargement du fichier CloudFormation sur S3 ...
Serverless: Télécharger des artefacts ...
Serverless: Téléchargement du fichier .zip du service sur S3 (5,44 Mo) ...
Serverless: validation du modèle ...
Serverless: Mise à jour de la pile ...
Serverless: Vérification de la progression de la mise à jour de la pile ...
..............
Serverless: mise à jour de la pile terminée ...
Des informations de service
service: serveurless-url-shortener
étape: dev
région: eu-west-1
pile: serverless-url-shortener-dev
clés api:
  Aucun
points finaux:
  POST - https://t2fgbcl26h.execute-api.eu-west-1.amazonaws.com/dev/
les fonctions:
  magasin: serveurless-url-shortener-dev-store
Serverless: Suppression des anciennes versions de service ...

Créer le frontend

Pour aider à la conception du front-end, nous utiliserons le framework PaperCSS. Nous allons également utiliser jQuery pour simplifier le travail avec le DOM et effectuer des requêtes AJAX. Il convient de noter que, dans un environnement de production, vous voudrez probablement créer deux dépendances plus légères, mais comme il s’agit d’un tutoriel, j’estime que cela est acceptable.

Créez un dossier statique pour que nous ayons un endroit où stocker notre code frontal.

Télécharger les dépendances

Enregistrez une copie de paper.min.css et de jquery-3.2.1.min.js dans notre dossier statique nouvellement créé. Il s'agit respectivement de versions réduites du framework PaperCSS et de la bibliothèque jQuery.

Ajouter le HTML

Créez un nouveau fichier appelé index.html dans le dossier statique et ajoutez le code HTML requis. Nous avons besoin d'un formulaire avec une entrée d'URL et un bouton pour le soumettre. Nous avons également besoin de quelque part pour mettre le résultat de tous les appels d'API, qui pour un appel d'API réussi serait l'URL raccourcie et pour un appel d'API infructueux, ce serait le message d'erreur.




  
  
   Raccourcisseur d'URL sans serveur </ title>
  <link href = "paper.min.css" rel = "stylesheet">
</ head>
<style>
  * {
    text-align: center;
  }</pre><pre>  #message {
    affichage: aucun;
  }
</ style>
<body>
  <div class = "row flex-center">
    <div class = "col-8 col">
      <h2> Raccourcisseur d’URL sans serveur </ h2>
      <formulaire action = "">
        <div class = "form-group">
          <label for = "url"> Entrez l'URL à raccourcir </ label>
          <entrée
            classe = "bloc d'entrée"
            name = "url"
            type = "url"
            id = "url"
            autocomplete = "off"
            nécessaire>
        </ div>
        <div id = "message" class = "alert alert-primaire"> </ div>
        <entrée
          class = "paper-btn"
          type = "submit"
          valeur = "raccourcir le lien">
      </ form>
      <p class = "padding-top">
        <a href="https://git.io/vbS8I">
          Voir ce projet sur Github
        </a>
      </ p>
    </ div>
  </ div>
</ body>
</ html></pre><p>Bien que cela ne soit pas indiqué dans le bloc de code ci-dessus par souci de brièveté, veillez à définir l'action de formulaire sur le point de terminaison de l'API affiché lors de l'exécution du déploiement sans serveur. Si vous n’avez plus accès à la sortie de votre terminal à partir de ce déploiement, vous pouvez trouver l’URL du noeud final à l’aide de la commande info sans serveur.</p><h4>Faire des requêtes API</h4><p>Avant d’écrire le code JavaScript pour envoyer des requêtes à notre API, commençons par charger jQuery en ajoutant une balise de script juste avant </ body> et en référençant le fichier réduit que nous avons téléchargé précédemment.</p><pre></ins><div class="neighbor-articles"><h4 class="ui header">Voir également</h4><a href="/article/how-to-convince-strangers-to-help-you-get-a-job-f29294/" title="Comment convaincre des étrangers de vous aider à trouver un emploi">Comment convaincre des étrangers de vous aider à trouver un emploi</a><a href="/article/does-facebook-even-know-how-to-control-facebook-a02f09/" title="Facebook sait-il même comment contrôler Facebook?">Facebook sait-il même comment contrôler Facebook?</a><a href="/article/how-to-prevent-burnout-in-the-workplace-aa2954/" title="Comment prévenir l'épuisement professionnel au travail">Comment prévenir l'épuisement professionnel au travail</a><a href="/article/flowchart-how-to-deal-with-rejection-db3cb4/" title="Organigramme: Comment traiter le rejet.">Organigramme: Comment traiter le rejet.</a><a href="/article/how-es6-classes-really-work-and-how-to-build-your-own-1a7d5a/" title="Comment les classes ES6 fonctionnent vraiment et comment construire les vôtres">Comment les classes ES6 fonctionnent vraiment et comment construire les vôtres</a></div></main><div class="push"></div></div><footer><div class="flags-footer"><a href="https://vi.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="vn flag"></i></a><a href="https://uk.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="ua flag"></i></a><a href="https://tr.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="tr flag"></i></a><a href="https://th.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="th flag"></i></a><a href="https://sv.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="ch flag"></i></a><a href="https://sr.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="rs flag"></i></a><a href="https://sl.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="si flag"></i></a><a href="https://sk.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="sk flag"></i></a><a href="https://ru.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="ru flag"></i></a><a href="https://ro.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="ro flag"></i></a><a href="https://pt.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="pt flag"></i></a><a href="https://pl.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="pl flag"></i></a><a href="https://de.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="de flag"></i></a><a href="https://ar.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="sa flag"></i></a><a href="https://bg.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="bg flag"></i></a><a href="https://cs.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="cz flag"></i></a><a href="https://da.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="dk flag"></i></a><a href="https://el.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="gr flag"></i></a><a href="https://ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="es flag"></i></a><a href="https://et.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="ee flag"></i></a><a href="https://fi.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="fi flag"></i></a><a href="https://hi.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="in flag"></i></a><a href="https://hr.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="hr flag"></i></a><a href="https://hu.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="hu flag"></i></a><a href="https://id.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="id flag"></i></a><a href="https://it.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="it flag"></i></a><a href="https://ja.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="jp flag"></i></a><a href="https://ko.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="kr flag"></i></a><a href="https://lt.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="lt flag"></i></a><a href="https://lv.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="lv flag"></i></a><a href="https://ms.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="my flag"></i></a><a href="https://nl.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="nl flag"></i></a><a href="https://no.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="no flag"></i></a><a href="https://uz.ceadesc.org/article/how-to-build-a-serverless-url-shortener-using-aws-lambda-and-s3-da940b/"><i class="uz flag"></i></a></div>ceadesc.org<!-- --> © <!-- -->2020<!-- --> </footer></div></div></div></body></html>