jQuery $ajax (),$.publicar el envío de "OPCIONES" como MÉTODO DE SOLICITUD en Firefox


Tener problemas con lo que pensé que era un plugin jQuery relativamente simple...

El plugin debería obtener datos de un script php a través de ajax para añadir opciones a un <select>. La solicitud ajax es bastante genérica:

$.ajax({
  url: o.url,
  type: 'post',
  contentType: "application/x-www-form-urlencoded",
  data: '{"method":"getStates", "program":"EXPLORE"}',
  success: function (data, status) {
    console.log("Success!!");
    console.log(data);
    console.log(status);
  },
  error: function (xhr, desc, err) {
    console.log(xhr);
    console.log("Desc: " + desc + "\nErr:" + err);
  }
});

Esto parece funcionar bien en Safari. En Firefox 3.5, el REQUEST_TYPE en el servidor siempre es 'OPTIONS', y los datos $_POST no aparecen. Apache registra la solicitud como tipo 'OPTIONS':

::1 - - [08/Jul/2009:11:43:27 -0500] "OPTIONS sitecodes.php HTTP/1.1" 200 46

¿Por qué esta llamada ajax funciona en Safari, pero no Firefox, y cómo ¿Lo arreglo para Firefox?

Response Headers
Date: Wed, 08 Jul 2009 21:22:17 GMT
Server:Apache/2.0.59 (Unix) PHP/5.2.6 DAV/2
X-Powered-By: PHP/5.2.6
Content-Length  46
Keep-Alive  timeout=15, max=100
Connection  Keep-Alive
Content-Type    text/html

Request Headers
Host    orderform:8888
User-Agent  Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1) Gecko/20090624 Firefox/3.5
Accept  text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language en-us,en;q=0.5
Accept-Encoding gzip,deflate
Accept-Charset  ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive  300
Connection  keep-alive
Origin  http://ux.inetu.act.org
Access-Control-Request-Method   POST
Access-Control-Request-Headers  x-requested-with

Aquí hay una imagen de la salida Firebug:

Author: VisioN, 2009-07-08

23 answers

El motivo del error es la misma política de origen. Solo le permite hacer XMLHttpRequests a su propio dominio. Vea si puede usar una devolución de llamada JSONP en su lugar:

$.getJSON( 'http://<url>/api.php?callback=?', function ( data ) { alert ( data ); } );
 165
Author: Jonas Skovmand,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-27 00:10:32

Usé el siguiente código en el lado de Django para interpretar la solicitud de OPCIONES y para establecer las cabeceras de Control de Acceso requeridas. Después de esto, mis solicitudes de dominios cruzados de Firefox comenzaron a funcionar. Como se dijo antes, el navegador primero envía la solicitud de OPCIONES y luego inmediatamente después de que el POST / GET

def send_data(request):
    if request.method == "OPTIONS": 
        response = HttpResponse()
        response['Access-Control-Allow-Origin'] = '*'
        response['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS'
        response['Access-Control-Max-Age'] = 1000
        # note that '*' is not valid for Access-Control-Allow-Headers
        response['Access-Control-Allow-Headers'] = 'origin, x-csrftoken, content-type, accept'
        return response
    if request.method == "POST":
        # ... 

Editar: parece ser que al menos en algunos casos también necesita agregar los mismos encabezados de Control de acceso a la respuesta real. Esto puede ser un poco confuso, ya que la solicitud parece tener éxito, pero Firefox no pasa el contenido de la respuesta al Javascript.

 55
Author: Juha Palomäki,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-10 14:29:34

Este artículo del mozilla developer center describe varios escenarios de solicitud entre dominios. El artículo parece indicar que una solicitud POST con el tipo de contenido 'application / x-www-form-urlencoded' debe enviarse como una ' solicitud simple '(sin una solicitud de OPCIONES' preflight'). Encontré, sin embargo, que Firefox envió la solicitud de OPCIONES, a pesar de que mi POST fue enviado con ese tipo de contenido.

Pude hacer que esto funcionara creando un manejador de solicitudes de opciones en el servidor, que establezca el encabezado de respuesta 'Access-Control-Allow-Origin 'en'*'. Puedes ser más restrictivo ajustándolo a algo específico, como ' http://someurl.com '. También, he leído que, supuestamente, se puede especificar una lista separada por comas de múltiples orígenes, pero no pude conseguir que esto funcione.

Una vez que Firefox recibe la respuesta a la solicitud de OPCIONES con un valor aceptable 'Access-Control-Allow-Origin', envía la solicitud POST.

 16
Author: Mike C,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-19 13:32:49

He solucionado este problema usando una solución completamente basada en Apache. En mi vhost / htaccess pongo el siguiente bloque:

# enable cross domain access control
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS"

# force apache to return 200 without executing my scripts
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule .* / [R=200,L]

Es posible que no necesite la última parte, dependiendo de lo que suceda cuando Apache ejecute su script de destino. El crédito va a la friendly ServerFault folk para la última parte.

 15
Author: Mark McDonald,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-13 12:13:35

Este PHP en la parte superior del script que responde parece funcionar. (Con Firefox 3.6.11. Todavía no he hecho muchas pruebas.)

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Max-Age: 1000');
if(array_key_exists('HTTP_ACCESS_CONTROL_REQUEST_HEADERS', $_SERVER)) {
    header('Access-Control-Allow-Headers: '
           . $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']);
} else {
    header('Access-Control-Allow-Headers: *');
}

if("OPTIONS" == $_SERVER['REQUEST_METHOD']) {
    exit(0);
}
 10
Author: Chad Clark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-28 20:56:57

Tuve el mismo problema con el envío de solicitudes a google maps, y la solución es bastante simple con jQuery 1.5-para el tipo de datos use dataType: "jsonp"

 7
Author: Slavomir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-10 02:40:03

El culpable es la solicitud de comprobación previa utilizando el método de OPCIONES

Para los métodos de solicitud HTTP que pueden causar efectos secundarios en los datos del usuario (en particular, para los métodos HTTP que no sean GET, o para el uso POST con ciertos tipos MIME), la especificación exige que los navegadores "comprueben previamente" la solicitud, solicitando los métodos compatibles del servidor con un método de solicitud de OPCIONES HTTP, y luego, tras la "aprobación" del servidor, enviando la solicitud real con el método de solicitud HTTP real.

Web especificación refiérase a: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

Resolví el problema agregando las siguientes líneas en Nginx conf.

    location / {
               if ($request_method = OPTIONS ) {
                   add_header Access-Control-Allow-Origin  "*";
                   add_header Access-Control-Allow-Methods "POST, GET, PUT, UPDATE, DELETE, OPTIONS";
                   add_header Access-Control-Allow-Headers "Authorization";
                   add_header Access-Control-Allow-Credentials  "true";
                   add_header Content-Length 0;
                   add_header Content-Type text/plain;
                   return 200;
               }
    location ~ ^/(xxxx)$ {
                if ($request_method = OPTIONS) {
                    rewrite ^(.*)$ / last;
                }
    }
 5
Author: thinkhy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-22 15:04:47

Estaba mirando a través de la fuente 1.3.2, cuando se utiliza JSONP, la solicitud se realiza mediante la construcción de un elemento de SCRIPT de forma dinámica, que pasa por la política del Mismo dominio del navegador. Naturalmente, no puede hacer una solicitud POST usando un elemento SCRIPT, el navegador obtendría el resultado usando GET.

Como está solicitando una llamada JSONP, el elemento SCRIPT no se genera, porque solo lo hace cuando el tipo de llamada AJAX se establece en GET.

Http://dev.jquery.com/ticket/4690

 4
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-22 19:51:10

Tuvimos un problema como este con ASP.Net. Nuestro IIS estaba devolviendo un Error Interno del Servidor al intentar ejecutar un jQuery $.post para obtener algún contenido html debido a que PageHandlerFactory estaba restringido a responder solo Verbos GET,HEAD,POST,DEBUG. Así que puedes cambiar esa restricción añadiendo el verbo " OPTIONS "a la lista o seleccionando"All Verbs"

Puede modificar eso en su Administrador de IIS, seleccionando su sitio web, luego seleccionando Asignaciones de controlador, haga doble clic en su PageHandlerFactory para *.archivos apx como usted necesidad (Utilizamos un grupo de aplicaciones integrado con framework 4.0). Haga clic en Solicitar restricciones, luego vaya a Verbs Tabn y aplique su modificación.

Ahora nuestra solicitud $.post funciona como se esperaba:)

 3
Author: fboiton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-22 15:00:56

Compruebe si la URL action de su formulario incluye la parte www del dominio, mientras que la página original que ha abierto se ve sin www.

Normalmente se hace para Urls Canónicas..

Luché durante horas antes de tropezar con este artículo y encontré el indicio de Cross Domain.

 2
Author: Bijay Rungta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-20 09:09:19

Parece que si o.url = 'index.php' y este archivo existe está bien y devuelve un mensaje de éxito en la consola. Devuelve un error si uso url: http://www.google.com

Si está haciendo una solicitud post, por qué no usar directamente el $.post método:

$.post("test.php", { func: "getNameAndTime" },
    function(data){
        alert(data.name); // John
        console.log(data.time); //  2pm
    }, "json");

Es mucho más simple.

 2
Author: Elzo Valugi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-22 14:57:24

He publicado un claro ejemplo de cómo resolver esto si controla el código del servidor del dominio al que está publicando. Esta respuesta se toca en este hilo, pero esto lo explica más claramente IMO.

¿Cómo envío una solicitud de PUBLICACIÓN entre dominios a través de JavaScript?

 1
Author: rynop,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:23

La solución a esto es:

  1. utilice el tipo de datos: json
  2. añade &callback=? a tu url

Esto funcionó en llamar a Facebook API y con Firefox. Firebug está usando GET en lugar de OPTIONS con las condiciones anteriores (ambas).

 1
Author: Antonio Gulli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-05 16:46:49

Otra posibilidad para evitar el problema es usar un script proxy. Ese método se describe para ejemplo aquí

 1
Author: Niehztog,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-22 14:59:33

¿Puedes probar esto sin

contentType:application/x-www-form-urlencoded

 0
Author: Mathias F,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-08 18:40:12

Intenta agregar la opción:

Tipo de datos:"json"

 0
Author: ScottE,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-10 12:51:32
 function test_success(page,name,id,divname,str)
{ 
 var dropdownIndex = document.getElementById(name).selectedIndex;
 var dropdownValue = document.getElementById(name)[dropdownIndex].value;
 var params='&'+id+'='+dropdownValue+'&'+str;
 //makerequest_sp(url, params, divid1);

 $.ajax({
    url: page,
    type: "post",
    data: params,
    // callback handler that will be called on success
    success: function(response, textStatus, jqXHR){
        // log a message to the console
        document.getElementById(divname).innerHTML = response;

        var retname = 'n_district';
        var dropdownIndex = document.getElementById(retname).selectedIndex;
        var dropdownValue = document.getElementById(retname)[dropdownIndex].value;
        if(dropdownValue >0)
        {
            //alert(dropdownValue);
            document.getElementById('inputname').value = dropdownValue;
        }
        else
        {
            document.getElementById('inputname').value = "00";
        }
        return;
        url2=page2; 
        var params2 = parrams2+'&';
        makerequest_sp(url2, params2, divid2);

     }
});         
}
 0
Author: Naser Gulzade,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-01 10:26:28

Tuve un problema similar al intentar usar la API de Facebook.

El único tipo de contenido que no envió la solicitud Preflighted parecía ser solo text/plain... no el resto de los parámetros mencionados en mozilla aquí

  • ¿Por qué es este el único navegador que hace esto?
  • ¿Por qué Facebook no conoce y acepta la solicitud de comprobación previa?

Para su información: El mencionado documento Moz sugiere que las cabeceras X-Lori deberían desencadenar una solicitud Preflighted ... se no lo hace.

 0
Author: Drew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-22 14:57:33

Necesita hacer algo de trabajo en el lado del servidor. Veo que está utilizando PHP en el lado del servidor, pero la solución para la aplicación web. NET está aquí: No se puede establecer content-type en 'application/json' en jQuery.ajax

Haga lo mismo en el script PHP y funcionará. Simplemente: En la primera solicitud, el navegador le pregunta al servidor si se le permite enviar dichos datos con dicho tipo y la segunda solicitud es la adecuada/permitida.

 0
Author: Fanda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:03:02

Intenta agregar lo siguiente:

dataType: "json",
ContentType: "application/json",
data: JSON.stringify({"method":"getStates", "program":"EXPLORE"}),  
 0
Author: Mary Jain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-09 13:22:48

Usé una url proxy para resolver un problema similar cuando quiero publicar datos en mi apache solr alojado en otro servidor. (Esta puede no ser la respuesta perfecta, pero resuelve mi problema.)

Siga esta URL: Usando Mode-Rewrite para proxy, agrego esta línea a mi httpd.conf:

 RewriteRule ^solr/(.*)$ http://ip:8983/solr$1 [P]

Por lo tanto, solo puedo publicar datos en / solr en lugar de publicar datos en http://ip:8983/solr / *. Luego estará publicando datos en el mismo origen.

 0
Author: Bernice,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-21 08:13:57

Ya tengo este código manejando bien mi situación cors en php:

header( 'Access-Control-Allow-Origin: '.CMSConfig::ALLOW_DOMAIN );
header( 'Access-Control-Allow-Headers: '.CMSConfig::ALLOW_DOMAIN );
header( 'Access-Control-Allow-Credentials: true' );

Y funcionaba bien local y remotamente, pero no para subidas cuando era remoto.

Algo sucede con apache/php O mi código, no me molesté en buscarlo, cuando solicitas OPCIONES devuelve mi encabezado con reglas cors pero con resultado 302. Por lo tanto, mi navegador no reconoce como una situación aceptable.

Lo que hice, basado en la respuesta de @Mark McDonald, es poner este código después de mi cabecera:

if( $_SERVER['REQUEST_METHOD'] === 'OPTIONS' )
{
    header("HTTP/1.1 202 Accepted");
    exit;
}

Ahora, al solicitar OPTIONS simplemente enviará el encabezado y el resultado 202.

 0
Author: Orlando Leite,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-15 15:14:35

Tenga en cuenta:

JSONP solo admite el método GET request.

*Enviar solicitud por firefox:*

$.ajax({
   type: 'POST',//<<===
   contentType: 'application/json',
   url: url,
   dataType: "json"//<<=============
    ...
});

Anterior solicitud enviar por OPCIONES (mientras ==>tipo: 'POST')!!!!

$.ajax({
    type: 'POST',//<<===
    contentType: 'application/json',
    url: url,
    dataType: "jsonp"//<<==============
    ...
});

Pero por encima de la solicitud enviar por OBTENER (mientras ==>tipo: 'POST')!!!!

Cuando esté en "comunicación entre dominios" , preste atención y tenga cuidado.

 -1
Author: M.Namjo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-01 15:47:06