ajax - plugin - jquery version




jQuery $.ajax(), $.post enviando "OPCIONES" como REQUEST_METHOD en Firefox (16)

¿Puedes probar esto sin

contentType:application/x-www-form-urlencoded

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

El complemento debe obtener datos de un script php a través de ajax para agregar 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 'OPCIONES', y los datos de $ _POST no aparecen. Apache registra la solicitud como tipo 'OPCIONES':

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

¿Por qué funcionaría esta llamada ajax en Safari, pero no en 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 de Firebug:


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

Hecho típicamente para las URL canónicas.

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


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

$.getJSON( 'http://<url>/api.php?callback=?', function ( data ) { alert ( data ); } );

Estaba buscando en la fuente 1.3.2, cuando uso JSONP, la solicitud se realiza mediante la creación de un elemento SCRIPT de forma dinámica, que supera la política del mismo dominio de los navegadores. Naturalmente, no puede realizar una solicitud POST utilizando un elemento SCRIPT, el navegador obtendría el resultado utilizando GET.

Cuando solicita una llamada JSONP, el elemento SCRIPT no se genera, porque solo hace esto cuando la llamada Tipo de AJAX se establece en GET.

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


Este PHP en la parte superior de la secuencia de comandos de respuesta parece funcionar. (Con Firefox 3.6.11. Aún no he realizado 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);
}


Intenta agregar la opción:

tipo de datos: "json"


Intenta agregar lo siguiente:

dataType: "json",
ContentType: "application/json",
data: JSON.stringify({"method":"getStates", "program":"EXPLORE"}),  

Necesitas hacer algún 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 el tipo de contenido en 'application / json' en jQuery.ajax

Haga lo mismo en el script PHP y funcionará. Simplemente: en la primera solicitud, el navegador pregunta al servidor si está autorizado para enviar dichos datos con ese tipo y la segunda solicitud es la correcta / permitida.


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


Por favor tenga en cuenta:

JSONP solo admite el método de solicitud GET.

* Enviar solicitud por firefox : *

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

La solicitud anterior envía por OPCIONES (mientras ==> escribe: 'POST' ) !!!!

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

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

Cuando se encuentre en "comunicación entre dominios", preste atención y tenga cuidado.


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 dataType use dataType: "jsonp"


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 PageHandlerFactory estaba restringido para responder solo los verbos GET,HEAD,POST,DEBUG . Así que puedes cambiar esa restricción agregando el verbo "OPCIONES" a la lista o seleccionando "Todos los verbos"

Puede modificar eso en su Administrador de IIS, seleccionando su sitio web, luego seleccionando Asignaciones de controladores, haciendo doble clic en su PageHandlerFactory para los archivos * .apx que necesite (utilizamos el grupo de aplicaciones integradas con Framework 4.0). Haga clic en Solicitar restricciones, luego vaya a Verbs Tabn y aplique su modificación.

Ahora nuestra solicitud de $.post está funcionando como se espera :)


Utilicé el siguiente código en el lado de Django para interpretar la solicitud de OPCIONES y para establecer los encabezados de control de acceso requeridos. Después de esto, mis solicitudes de dominio cruzado de Firefox comenzaron a funcionar. Como se dijo antes, el navegador envía primero la solicitud de OPCIONES y luego, inmediatamente después, 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":
        # ... 

Edición: parece ser que al menos en algunos casos también debe 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.


Ya tengo este código manejando bien mi situación 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 localmente y de forma remota, pero no para cargas cuando estaba remoto.

Algo sucedió con apache / php O mi código, no me molesté en buscarlo, cuando solicitas OPCIONES, devuelve mi encabezado con reglas de cors, pero con 302 resultados. 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 encabezado:

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

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


 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);

     }
});         
}




jquery