{"id":1626,"date":"2024-08-02T10:42:47","date_gmt":"2024-08-02T08:42:47","guid":{"rendered":"https:\/\/blog.sutilweb.eu\/?page_id=1626"},"modified":"2024-08-02T10:42:48","modified_gmt":"2024-08-02T08:42:48","slug":"005-envio-formulario-y-cors-con-fetch-y-php","status":"publish","type":"page","link":"https:\/\/sutilweb.eu\/index.php\/lenguajes\/javascript\/javascript-practico\/17-ejercicios-con-ajax\/005-envio-formulario-y-cors-con-fetch-y-php\/","title":{"rendered":"005. Env\u00edo Formulario y CORS con Fetch y PHP"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">En este cap\u00edtulo trabajaremos del lado del servidor con <strong>PHP<\/strong> para poder enviar nuestros propios formularios sin necesidad de <strong>APIs externas<\/strong>. Trabajaremos con el archivo del cap\u00edtulo anterior, sobre el que modificaremos algunos detalles como son la petici\u00f3n del <strong>endpoint<\/strong> al que consulta nuestra funci\u00f3n <em>fetch()<\/em>. Todo lo dem\u00e1s funciona exactamente igual.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p class=\"wp-block-paragraph\">Veremos un concepto muy importante denominado <strong>CORS<\/strong> (<strong>Cross-Origin Resource Sharing<\/strong>) o intercambio de recursos de origen cruzado, es una pol\u00edtica de normas que nos dice que todas las peticiones <strong>AJAX<\/strong> en teor\u00eda tendr\u00edan que estar en el mismo servidor. Tendr\u00edamos que activar en nuestro archivo <strong>html<\/strong> y <strong>php<\/strong> la petici\u00f3n <strong>CORS<\/strong>, es decir el intercambio entre dominios.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Al archivo del cap\u00edtulo anterior, en este cap\u00edtulo lo vamos a llamar <em>contact-form-php.html<\/em>. Y tambi\u00e9n vamos a crear un archivo PHP denominado <em>send_mail.php<\/em>, que ser\u00e1 el que env\u00ede el formulario. Veamos la sintaxis de nuestros archivos.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Sintaxis del archivos <em>contact-form-php.html<\/em>.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">&lt;!DOCTYPE html&gt;\n&lt;html lang=\"en\"&gt;\n&nbsp; &lt;head&gt;\n&nbsp; &nbsp; &lt;meta charset=\"UTF-8\" \/&gt;\n&nbsp; &nbsp; &lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" \/&gt;\n&nbsp; &nbsp; &lt;title&gt;Env\u00edo de formulario con Fetch y PHP&lt;\/title&gt;\n&nbsp; &nbsp; &lt;style&gt;\n&nbsp; &nbsp; &nbsp; html {\n&nbsp; &nbsp; &nbsp; &nbsp; box-sizing: border-box;\n&nbsp; &nbsp; &nbsp; &nbsp; font-family: sans-serif;\n&nbsp; &nbsp; &nbsp; &nbsp; font-size: 16px;\n&nbsp; &nbsp; &nbsp; }\n\n&nbsp; &nbsp; &nbsp; *,\n&nbsp; &nbsp; &nbsp; *::before,\n&nbsp; &nbsp; &nbsp; *::after {\n&nbsp; &nbsp; &nbsp; &nbsp; box-sizing: inherit;\n&nbsp; &nbsp; &nbsp; }\n\n&nbsp; &nbsp; &nbsp; \/* **** ContactForm Validations **** *\/\n&nbsp; &nbsp; &nbsp; .contact-form {\n&nbsp; &nbsp; &nbsp; &nbsp; --form-ok-color: #4caf50;\n&nbsp; &nbsp; &nbsp; &nbsp; --form-error-color: #f44336;\n&nbsp; &nbsp; &nbsp; &nbsp; margin-left: auto;\n&nbsp; &nbsp; &nbsp; &nbsp; margin-right: auto;\n&nbsp; &nbsp; &nbsp; &nbsp; width: 80%;\n&nbsp; &nbsp; &nbsp; }\n\n&nbsp; &nbsp; &nbsp; .contact-form &gt; * {\n&nbsp; &nbsp; &nbsp; &nbsp; padding: 0.5rem;\n&nbsp; &nbsp; &nbsp; &nbsp; margin: 1rem auto;\n&nbsp; &nbsp; &nbsp; &nbsp; display: block;\n&nbsp; &nbsp; &nbsp; &nbsp; width: 100%;\n&nbsp; &nbsp; &nbsp; }\n\n&nbsp; &nbsp; &nbsp; .contact-form textarea {\n&nbsp; &nbsp; &nbsp; &nbsp; resize: none;\n&nbsp; &nbsp; &nbsp; }\n\n&nbsp; &nbsp; &nbsp; .contact-form legend,\n&nbsp; &nbsp; &nbsp; .contact-form-response {\n&nbsp; &nbsp; &nbsp; &nbsp; font-size: 1.5rem;\n&nbsp; &nbsp; &nbsp; &nbsp; font-weight: bold;\n&nbsp; &nbsp; &nbsp; &nbsp; text-align: center;\n&nbsp; &nbsp; &nbsp; }\n\n&nbsp; &nbsp; &nbsp; .contact-form input,\n&nbsp; &nbsp; &nbsp; .contact-form textarea {\n&nbsp; &nbsp; &nbsp; &nbsp; font-size: 1rem;\n&nbsp; &nbsp; &nbsp; &nbsp; font-family: sans-serif;\n&nbsp; &nbsp; &nbsp; }\n\n&nbsp; &nbsp; &nbsp; .contact-form input[type=\"submit\"] {\n&nbsp; &nbsp; &nbsp; &nbsp; width: 50%;\n&nbsp; &nbsp; &nbsp; &nbsp; font-weight: bold;\n&nbsp; &nbsp; &nbsp; &nbsp; cursor: pointer;\n&nbsp; &nbsp; &nbsp; }\n\n&nbsp; &nbsp; &nbsp; .contact-form *::placeholder {\n&nbsp; &nbsp; &nbsp; &nbsp; color: #000;\n&nbsp; &nbsp; &nbsp; }\n\n&nbsp; &nbsp; &nbsp; .contact-form [required]:valid {\n&nbsp; &nbsp; &nbsp; &nbsp; border: thin solid var(--form-ok-color);\n&nbsp; &nbsp; &nbsp; }\n\n&nbsp; &nbsp; &nbsp; .contact-form [required]:invalid {\n&nbsp; &nbsp; &nbsp; &nbsp; border: thin solid var(--form-error-color);\n&nbsp; &nbsp; &nbsp; }\n\n&nbsp; &nbsp; &nbsp; .contact-form-error {\n&nbsp; &nbsp; &nbsp; &nbsp; margin-top: -1rem;\n&nbsp; &nbsp; &nbsp; &nbsp; font-size: 80%;\n&nbsp; &nbsp; &nbsp; &nbsp; background-color: var(--form-error-color);\n&nbsp; &nbsp; &nbsp; &nbsp; color: #fff;\n&nbsp; &nbsp; &nbsp; &nbsp; transition: all 800ms ease;\n&nbsp; &nbsp; &nbsp; }\n\n&nbsp; &nbsp; &nbsp; .contact-form-error.is-active {\n&nbsp; &nbsp; &nbsp; &nbsp; display: block;\n&nbsp; &nbsp; &nbsp; &nbsp; animation: show-message 1s 1 normal 0s ease-out both;\n&nbsp; &nbsp; &nbsp; }\n\n&nbsp; &nbsp; &nbsp; .contact-form-loader {\n&nbsp; &nbsp; &nbsp; &nbsp; text-align: center;\n&nbsp; &nbsp; &nbsp; }\n\n&nbsp; &nbsp; &nbsp; .none {\n&nbsp; &nbsp; &nbsp; &nbsp; display: none;\n&nbsp; &nbsp; &nbsp; }\n\n&nbsp; &nbsp; &nbsp; @keyframes show-message {\n&nbsp; &nbsp; &nbsp; &nbsp; 0% {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; visibility: hidden;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; opacity: 0;\n&nbsp; &nbsp; &nbsp; &nbsp; }\n&nbsp; &nbsp; &nbsp; &nbsp; 100% {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; visibility: visible;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; opacity: 1;\n&nbsp; &nbsp; &nbsp; &nbsp; }\n&nbsp; &nbsp; &nbsp; }\n&nbsp; &nbsp; &lt;\/style&gt;\n&nbsp; &lt;\/head&gt;\n\n&nbsp; &lt;body&gt;\n&nbsp; &nbsp; &lt;form class=\"contact-form\"&gt;\n&nbsp; &nbsp; &nbsp; &lt;legend&gt;Env\u00eda tus comentarios&lt;\/legend&gt;\n&nbsp; &nbsp; &nbsp; &lt;input\n&nbsp; &nbsp; &nbsp; &nbsp; type=\"text\"\n&nbsp; &nbsp; &nbsp; &nbsp; name=\"name\"\n&nbsp; &nbsp; &nbsp; &nbsp; placeholder=\"Escribe tu nombre\"\n&nbsp; &nbsp; &nbsp; &nbsp; title=\"Nombre s\u00f3lo acepta letras y espacios en blanco\"\n&nbsp; &nbsp; &nbsp; &nbsp; pattern=\"^[A-Za-z\u00d1\u00f1\u00c1\u00e1\u00c9\u00e9\u00cd\u00ed\u00d3\u00f3\u00da\u00fa\u00dc\u00fc\\s]+$\"\n&nbsp; &nbsp; &nbsp; &nbsp; required\n&nbsp; &nbsp; &nbsp; \/&gt;\n&nbsp; &nbsp; &nbsp; &lt;input\n&nbsp; &nbsp; &nbsp; &nbsp; type=\"email\"\n&nbsp; &nbsp; &nbsp; &nbsp; name=\"email\"\n&nbsp; &nbsp; &nbsp; &nbsp; placeholder=\"Escribe tu correo\"\n&nbsp; &nbsp; &nbsp; &nbsp; title=\"Email incorrecto\"\n&nbsp; &nbsp; &nbsp; &nbsp; pattern=\"^[a-z0-9]+(\\.[_a-z0-9]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*(\\.[a-z]{2,15})$\"\n&nbsp; &nbsp; &nbsp; &nbsp; required\n&nbsp; &nbsp; &nbsp; \/&gt;\n&nbsp; &nbsp; &nbsp; &lt;input\n&nbsp; &nbsp; &nbsp; &nbsp; type=\"text\"\n&nbsp; &nbsp; &nbsp; &nbsp; name=\"subject\"\n&nbsp; &nbsp; &nbsp; &nbsp; placeholder=\"Asunto a tratar\"\n&nbsp; &nbsp; &nbsp; &nbsp; title=\"El asunto es requerido\"\n&nbsp; &nbsp; &nbsp; &nbsp; required\n&nbsp; &nbsp; &nbsp; \/&gt;\n&nbsp; &nbsp; &nbsp; &lt;textarea\n&nbsp; &nbsp; &nbsp; &nbsp; name=\"comments\"\n&nbsp; &nbsp; &nbsp; &nbsp; cols=\"50\"\n&nbsp; &nbsp; &nbsp; &nbsp; rows=\"5\"\n&nbsp; &nbsp; &nbsp; &nbsp; placeholder=\"Escribe tus comentarios\"\n&nbsp; &nbsp; &nbsp; &nbsp; data-pattern=\"^.{1,255}$\"\n&nbsp; &nbsp; &nbsp; &nbsp; title=\"Tu comentario no debe sobrepasar los 255 caracteres\"\n&nbsp; &nbsp; &nbsp; &nbsp; required\n&nbsp; &nbsp; &nbsp; &gt;&lt;\/textarea&gt;\n&nbsp; &nbsp; &nbsp; &lt;input type=\"submit\" value=\"Enviar\" \/&gt;\n&nbsp; &nbsp; &nbsp; &lt;div class=\"contact-form-loader none\"&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &lt;img src=\"loader.svg\" alt=\"Cargando\" \/&gt;\n&nbsp; &nbsp; &nbsp; &lt;\/div&gt;\n&nbsp; &nbsp; &nbsp; &lt;div class=\"contact-form-response none\"&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &lt;p&gt;Los datos han sido enviados&lt;\/p&gt;\n&nbsp; &nbsp; &nbsp; &lt;\/div&gt;\n&nbsp; &nbsp; &lt;\/form&gt;\n\n&nbsp; &nbsp; &lt;script&gt;\n&nbsp; &nbsp; &nbsp; const d = document;\n&nbsp; &nbsp; &nbsp;\n       function contactForm() {\n&nbsp; &nbsp; &nbsp; &nbsp; const $form = d.querySelector(\".contact-form\"),\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $inputs = d.querySelectorAll(\".contact-form [required]\");\n&nbsp; &nbsp; &nbsp; &nbsp; \/\/ console.log($imputs);\n&nbsp; &nbsp; &nbsp; &nbsp; $inputs.forEach((input) =&gt; {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const $span = d.createElement(\"span\");\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $span.id = input.name;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $span.textContent = input.title;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $span.classList.add(\"contact-form-error\", \"none\");\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; input.insertAdjacentElement(\"afterend\", $span);\n&nbsp; &nbsp; &nbsp; &nbsp; });\n\n&nbsp; &nbsp; &nbsp; &nbsp; d.addEventListener(\"keyup\", (e) =&gt; {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (e.target.matches(\".contact-form [required]\")) {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let $input = e.target,\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pattern = $input.pattern || $input.dataset.pattern;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \/\/ console.log($input, pattern);\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (pattern &amp;&amp; $input.value !== \"\") {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \/\/ console.log(\"El input tiene patr\u00f3n\");\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let regex = new RegExp(pattern);\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return !regex.exec($input.value)\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ? d.getElementById($input.name).classList.add(\"is-active\")\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : d.getElementById($input.name).classList.remove(\"is-active\");\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }\n\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!pattern) {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \/\/ console.log(\"El input NO tiene patr\u00f3n\");\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return $input.value === \"\"\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ? d.getElementById($input.name).classList.add(\"is-active\")\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : d.getElementById($input.name).classList.remove(\"is-active\");\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }\n&nbsp; &nbsp; &nbsp; &nbsp; });\n\n&nbsp; &nbsp; &nbsp; &nbsp; d.addEventListener(\"submit\", (e) =&gt; {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.preventDefault();\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const $loader = d.querySelector(\".contact-form-loader\"),\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $response = d.querySelector(\".contact-form-response\");\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $loader.classList.remove(\"none\");\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fetch(\"send_mail.php\", {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; method: \"POST\",\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; body: new FormData(e.target),\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mode: \"cors\",\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; })\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .then((res) =&gt; (res.ok ? res.json() : Promise.reject(res)))\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .then((json) =&gt; {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $loader.classList.add(\"none\");\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $response.classList.remove(\"none\");\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $response.innerHTML = `&lt;p&gt;${json.message}&lt;\/p&gt;`;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $form.reset();\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; })\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .catch((err) =&gt; {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(err);\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let message =\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; err.statusText || \"Ocurri\u00f3 un error al enviar el formulario\";\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $response.innerHTML = `&lt;p&gt;Error ${err.status}: ${message}&lt;\/p&gt;`;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; })\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .finally(() =&gt; {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setTimeout(() =&gt; {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $response.classList.add(\"none\");\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $response.innerHTML = ``;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }, 3000);\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });\n&nbsp; &nbsp; &nbsp; &nbsp; });\n&nbsp; &nbsp; &nbsp; }\n\n&nbsp; &nbsp; &nbsp; d.addEventListener(\"DOMContentLoaded\", contactForm());\n&nbsp; &nbsp; &lt;\/script&gt;\n&nbsp; &lt;\/body&gt;\n&lt;\/html&gt;<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Sintaxis del archivo <em>send_mail.php<\/em>.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">&lt;?php\nif(isset($_POST)){\n&nbsp; &nbsp; error_reporting(0);\n\n&nbsp; &nbsp; \/\/ Variables que vienen del formulario\n&nbsp; &nbsp; $name = $_POST[\"name\"];\n&nbsp; &nbsp; $email = $_POST[\"email\"];\n&nbsp; &nbsp; $subject = $_POST[\"subject\"];\n&nbsp; &nbsp; $comments = $_POST[\"comments\"];\n\n&nbsp; &nbsp; \/\/ Variables que necesito para enviar la petici\u00f3n\n&nbsp; &nbsp; $domain = $_POST[\"HTTP_HOST\"];\n&nbsp; &nbsp; $to = \"franwebsite@gmail.com\";\n&nbsp; &nbsp; $subject = \"Contacto desde el formulario del sitio $domain: $subject\";\n&nbsp; &nbsp; $message = \"\n&nbsp; &nbsp; &lt;p&gt;\n&nbsp; &nbsp; Datos enviados desde el formulario del sitio &lt;b&gt;$domain&lt;\/b&gt;\n&nbsp; &nbsp; &lt;\/p&gt;\n\n&nbsp; &nbsp; &lt;ul&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &lt;li&gt;Nombre: &lt;b&gt;$name&lt;\/b&gt;&lt;\/li&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &lt;li&gt;Email: &lt;b&gt;$email&lt;\/b&gt;&lt;\/li&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &lt;li&gt;Asunto: $subject&lt;\/li&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &lt;li&gt;Comentarios: $comments&lt;\/li&gt;\n&nbsp; &nbsp; &lt;\/ul&gt;\n&nbsp; &nbsp; \";\n\n&nbsp; &nbsp; $headers = \"MIME - Version 1.0 \\r\\n\".\"Content-Type: text\/html; charset=utf-8\\r\\n\".\n&nbsp; &nbsp; \"From: Env\u00edo Autom\u00e1tico No Responder &lt;no-replay@$domain&gt;\";\n&nbsp; &nbsp; $send_mail = mail($to, $subject, $message, $headers);\n\n&nbsp; &nbsp; if($send_mail) {\n&nbsp; &nbsp; &nbsp; &nbsp; $res = [\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \"err\" =&gt; false,\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \"message\" =&gt; \"Tus datos han sido enviados\"\n&nbsp; &nbsp; &nbsp; &nbsp; ];\n&nbsp; &nbsp; } else {\n&nbsp; &nbsp; &nbsp; &nbsp; $res = [\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \"err\" =&gt; true,\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \"message\" =&gt; \"Error al enviar los datos, int\u00e9ntalo nuevamente\"\n&nbsp; &nbsp; &nbsp; &nbsp; ];\n&nbsp; &nbsp; }\n\n&nbsp; &nbsp; \/\/ header(\"Access-Control-Allow-Origin: https:\/\/sutilweb.eu\")\n&nbsp; &nbsp; header(\"Access-Control-Allow-Origin: *\");\n&nbsp; &nbsp; header(\"Content-Type: application\/json\");\n&nbsp; &nbsp; echo json_encode($res);\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>En este cap\u00edtulo trabajaremos del lado del servidor con PHP para poder enviar nuestros propios formularios sin necesidad de APIs externas. Trabajaremos con el archivo del cap\u00edtulo anterior, sobre el que modificaremos algunos detalles como son la petici\u00f3n del endpoint al que consulta nuestra funci\u00f3n fetch(). Todo lo dem\u00e1s funciona exactamente igual.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":1609,"menu_order":4,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_uag_custom_page_level_css":"","site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"class_list":["post-1626","page","type-page","status-publish","hentry"],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":"Sutil Web","author_link":"https:\/\/sutilweb.eu\/index.php\/author\/sutilweb\/"},"uagb_comment_info":0,"uagb_excerpt":"En este cap\u00edtulo trabajaremos del lado del servidor con PHP para poder enviar nuestros propios formularios sin necesidad de APIs externas. Trabajaremos con el archivo del cap\u00edtulo anterior, sobre el que modificaremos algunos detalles como son la petici\u00f3n del endpoint al que consulta nuestra funci\u00f3n fetch(). Todo lo dem\u00e1s funciona exactamente igual.","_links":{"self":[{"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/pages\/1626","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/comments?post=1626"}],"version-history":[{"count":2,"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/pages\/1626\/revisions"}],"predecessor-version":[{"id":1628,"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/pages\/1626\/revisions\/1628"}],"up":[{"embeddable":true,"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/pages\/1609"}],"wp:attachment":[{"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/media?parent=1626"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}