{"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&#8230;<\/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":"","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...","_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}]}}