# L'attribut action des formulaires HTML, expliqué

> Ce que fait l'attribut action d'un formulaire, comment les valeurs relatives et vides sont résolues, comment formaction envoie un formulaire à deux endroits, et pourquoi les hébergeurs statiques répondent 405.

Publié le 2026-10-25 · https://ikiform.com/fr/guides/html-form-submission/action-attribute

L'attribut `action` est l'URL à laquelle un formulaire envoie ses données. Une valeur relative est résolue par rapport à l'adresse de la page, une valeur vide ou absente désigne la page elle-même, et le `formaction` d'un bouton d'envoi la remplace pour ce bouton. Sur un site statique, définissez-la sur l'URL complète d'un backend de formulaires comme `https://ikiform.com/f/<formId>`, car votre propre hébergeur ne peut pas recevoir le POST.

La plupart des formulaires cassés sur les sites statiques le sont à cause de ce seul attribut. Le balisage semble correct, le bouton fonctionne, et le navigateur affiche un `405` ou une page blanche, parce que les données sont parties vers un endroit qui ne peut pas les recevoir. Cette page montre exactement où une `action` donnée envoie les données, puis utilise `formaction` pour diriger un même formulaire vers deux boîtes de réception.

## Ce qui change ici

`action` est une URL comme n'importe quel `href`, à une nuance près : un formulaire sans `action` ne reste pas inactif, il envoie à la page sur laquelle il se trouve. Sur un site rendu côté serveur, cette page peut traiter l'envoi. Sur un hébergeur statique, elle ne le peut pas, donc une `action` absente ou relative n'échoue qu'après le déploiement.

## Où chaque valeur envoie les données

Prenons une page à `https://example.com/company/contact.html` et cinq formulaires dessus :

`contact.html`:

```html
<form action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post">
<form action="/api/contact" method="post">
<form action="send" method="post">
<form action="" method="post">
<form method="post">
```

| action | Résolue en | Sur un hébergeur statique |
| --- | --- | --- |
| `https://ikiform.com/f/frm_...` | Exactement cette URL | Fonctionne. Ikiform reçoit le POST |
| `/api/contact` | `https://example.com/api/contact` | Ne fonctionne que si votre hébergeur exécute une fonction à ce chemin |
| `send` | `https://example.com/company/send`, relative au dossier | `405` ou `404` |
| `""` (empty) | La page elle-même, `contact.html` | `405` sur la plupart des hébergeurs statiques |
| Absente | La page elle-même | `405` sur la plupart des hébergeurs statiques |

Schéma : Comment le navigateur transforme l'attribut action d'un formulaire en URL d'envoi

1. Une action absolue est utilisée telle qu'elle est écrite, donc l'envoi atteint Ikiform, qui répond par une redirection.
2. Une action relative, vide ou absente est résolue par rapport à l'adresse de la page, ou par rapport à un élément base si la page en a un.
3. L'envoi part alors vers votre propre hébergeur. Un hébergeur statique ne sert que des fichiers, donc il refuse le POST, généralement avec 405.

Si la barre d'adresse affiche votre propre domaine juste après l'envoi, l'action était relative.

> Un élément `<base href>` dans le head de la page change la résolution de toutes les URL relatives, y compris `action`. Certains créateurs de sites et configurations d'applications monopages en ajoutent un. Utilisez une URL complète et cela n'a plus d'importance.

### Vérifier ce que le navigateur utilisera

Dans la console du navigateur, l'attribut et la propriété diffèrent. `getAttribute` renvoie ce que vous avez écrit ; la propriété `action` renvoie l'URL résolue vers laquelle le navigateur enverra réellement :

`Console`:

```js
const form = document.querySelector("form");
form.getAttribute("action");
form.action;
```

Si `form.action` affiche votre propre domaine, c'est là que vont les données. Les créateurs de sites comme Webflow et Framer définissent souvent `action` depuis leur propre panneau de paramètres, donc vérifiez la page publiée, pas votre source. Les [guides des créateurs de sites](https://ikiform.com/fr/docs/guides/site-builders.md) indiquent où chacun la conserve.

## Un formulaire, deux boîtes de réception

Le `formaction` d'un bouton d'envoi remplace l'`action` du formulaire pour ce bouton uniquement. Ici, un même ensemble de champs va vers deux formulaires Ikiform. **Ask support** envoie au formulaire du support, **Talk to sales** au formulaire commercial, et chaque formulaire Ikiform envoie un e-mail à ses propres destinataires :

`contact.html`:

```html
<form action="https://ikiform.com/f/frm_supportxxxxxxxxx" method="post">
  <label for="email">Email</label>
  <input id="email" name="email" type="email" autocomplete="email" required />

  <label for="message">How can we help?</label>
  <textarea id="message" name="message" rows="5" required></textarea>

  <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
  <button>Ask support</button>
  <button formaction="https://ikiform.com/f/frm_salesxxxxxxxxxxx">Talk to sales</button>
</form>
```

- Chaque formulaire Ikiform a ses propres destinataires de notifications, paramètres anti-spam et webhooks, donc le support et l'équipe commerciale ne voient jamais le courrier de l'autre.
- Les deux formulaires ont besoin de la même définition de champs, ou d'aucune. Avec des champs définis, un champ qu'un formulaire ne connaît pas est refusé avec `422`.
- Les autres attributs `form*` fonctionnent de la même façon : `formmethod`, `formenctype`, `formnovalidate` et `formtarget`. Un bouton **Save draft** avec `formnovalidate` ignore les vérifications du navigateur.
- `formaction` ne fonctionne que sur les boutons d'envoi : `<button>`, `<input type="submit">` et `<input type="image">`.

L'alternative est un seul formulaire Ikiform avec un champ `topic`, et un tri par sujet dans un webhook ou dans les filtres de votre boîte de réception. Cela garde une seule liste et un seul export. Deux formulaires sont plus simples quand les deux équipes ne doivent pas du tout partager de destinataires.

## action avec des paramètres d'URL

Avec `method="get"`, le navigateur remplace les paramètres d'URL de l'action par les champs du formulaire. Le `lang=de` du premier formulaire ci-dessous disparaît silencieusement ; le second le garde sous forme d'input masqué :

`search.html`:

```html
<form action="/search?lang=de" method="get">
  <input name="q" />
</form>

<form action="/search" method="get">
  <input name="q" />
  <input type="hidden" name="lang" value="de" />
</form>
```

Avec `method="post"`, les paramètres d'URL sont conservés, car les champs vont dans le corps. Cela ne change rien pour Ikiform : les paramètres de requête de l'URL de l'endpoint ne sont pas stockés, donc utilisez des inputs masqués pour les valeurs que vous voulez conserver.

## Inputs en dehors du formulaire

Les mises en page ont parfois besoin d'un input qui n'est pas dans l'élément `<form>`, comme une inscription en pied de page à côté d'autres contenus. L'attribut `form` d'un input ou d'un bouton le rattache à un formulaire par son `id`, et il envoie à l'`action` de ce formulaire :

`footer.html`:

```html
<form id="newsletter" action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post"></form>

<footer>
  <input form="newsletter" name="email" type="email" required />
  <button form="newsletter">Subscribe</button>
</footer>
```

## Actions mailto: et javascript:

`action="mailto:you@example.com"` demande à l'application de messagerie du visiteur d'ouvrir un message avec les champs. Rien n'est envoyé s'il n'a pas d'application de messagerie configurée et n'appuie pas sur envoyer, et vous ne savez jamais qu'il a essayé. `action="javascript:..."` exécute du code au lieu d'envoyer et est bloqué par la plupart des politiques de sécurité du contenu. Les deux méritent d'être remplacés par un vrai endpoint.

## Vérifiez que tout fonctionne

1. Dans **Allowed domains** du formulaire, ajoutez le domaine de votre site, plus `localhost` pendant le développement. Laissez vide pour accepter les envois de partout.
2. Ouvrez la page publiée, pas votre source, et exécutez `document.querySelector("form").action` dans la console. Elle affiche votre URL Ikiform complète.
3. Envoyez le formulaire. Le panneau Réseau montre un POST vers `ikiform.com` qui a reçu `303`, pas un POST vers votre propre domaine.
4. Dans le formulaire à deux boîtes de réception, envoyez une fois avec chaque bouton. Chaque soumission apparaît sous son propre formulaire dans le tableau de bord.
5. Vérifiez la boîte de réception de chaque destinataire des notifications. Chacun reçoit un e-mail avec les champs, et **Reply** répond à l'expéditeur quand le formulaire a un champ `email`.

## Pièges

| Problème | Cause et solution |
| --- | --- |
| `405 Method Not Allowed` depuis votre propre domaine | L'action est relative, vide ou absente, donc l'envoi est parti vers votre hébergeur statique. Utilisez l'URL Ikiform complète |
| `404 not_found` depuis ikiform.com | L'identifiant de formulaire dans l'action est erroné, ou le formulaire a été supprimé. Copiez l'endpoint depuis la page du formulaire dans le tableau de bord |
| Le créateur de sites réinitialise sans cesse l'action | Certains créateurs de sites contrôlent l'`action` de leur bloc de formulaire. Utilisez leur paramètre d'action personnalisée, ou une intégration avec votre propre balisage |
| Le navigateur avertit que le formulaire n'est pas sécurisé | L'action utilise `http:` sur une page `https:`. L'endpoint d'Ikiform est en `https:` uniquement ; corrigez le schéma |
| Les champs d'un second formulaire sont envoyés aussi | Les formulaires ne peuvent pas être imbriqués. Le navigateur ferme le formulaire extérieur à la balise `<form>` intérieure. Utilisez plutôt l'attribut `form` |

Pour le déroulement complet d'un envoi, du clic à la redirection, consultez la [vue d'ensemble](https://ikiform.com/fr/guides/html-form-submission.md#how-it-works). Tout ce que l'endpoint accepte se trouve dans [Formulaires HTML](https://ikiform.com/fr/docs/html.md).

## Questions

### Que se passe-t-il si un formulaire n'a pas d'attribut action ?

Il envoie à la page sur laquelle il se trouve. Cela fonctionne quand votre serveur traite les envois à cette URL, mais sur un hébergeur statique cela échoue, généralement avec 405 Method Not Allowed.

### Quelle est la différence entre action et formaction ?

action se définit sur le formulaire et s'applique à chaque envoi. formaction se définit sur un bouton d'envoi et remplace action quand ce bouton est utilisé, donc un même formulaire peut envoyer à deux endroits.

### L'action du formulaire peut-elle être une URL sur un autre domaine ?

Oui. Les navigateurs envoient en cross-site sans configuration particulière, c'est ainsi qu'une page statique envoie vers un backend de formulaires. Le serveur qui reçoit décide de l'accepter ou non ; Ikiform compare l'origine de la page aux domaines autorisés du formulaire.

### Pourquoi mes paramètres d'URL disparaissent-ils de l'URL d'action ?

Avec la méthode get, le navigateur remplace les paramètres d'URL de l'action par les propres champs du formulaire. Déplacez chaque paramètre dans un input masqué. Avec la méthode post, les paramètres d'URL sont conservés.

## Autres guides

- [Envoi de formulaire HTML](https://ikiform.com/fr/guides/html-form-submission.md): Ce que fait un navigateur quand un formulaire est envoyé : quels champs il transmet, comment il les encode, ce que le serveur doit répondre, et comment Ikiform répond.
- [Redirection après envoi](https://ikiform.com/fr/guides/html-form-submission/redirect-after-submit.md): Envoyez les visiteurs vers votre propre page de remerciement après l'envoi d'un formulaire : la redirection 303, le champ _redirect, les domaines autorisés et l'effet d'un rafraîchissement.
- [Sans rechargement de page](https://ikiform.com/fr/guides/html-form-submission/without-page-reload.md): Envoyez un formulaire avec fetch et FormData pour que le visiteur reste sur la page, avec erreurs de champ, état de chargement, nouvelles tentatives et solution de repli quand les scripts échouent.
- [Validation de formulaire](https://ikiform.com/fr/guides/html-form-submission/validation.md): Validez un formulaire avec required, type, pattern et min, stylisez les erreurs avec :user-invalid, et imposez les mêmes règles sur le serveur avec des définitions de champs.
