Ajax, jQuery и JSONP - PullRequest
       2

Ajax, jQuery и JSONP

4 голосов
/ 23 мая 2011

Кажется, что я могу получить данные JSON из другого домена, используя метод getJSON jQuery (см .: http://docs.jquery.com/Getjson). Однако это работает только для HTTP GET.

Что делать, если мне нужно что-то POST и получить ответ JSON? Как бы я это сделал в jQuery / Ajax?

Ответы [ 4 ]

4 голосов
/ 23 мая 2011

Невозможно отправлять запросы на удаленный сервер с клиента, используя только jQuery, начиная с версии 1.6.1, во всех браузерах.Если вы попытаетесь сделать запрос XHttpRequest любого вида на сервер в другом домене, чем документ, некоторые браузеры просто не смогут его завершить.Запросы JSONP к удаленным серверам обрабатываются путем создания тега сценария, src для которого является URL-адресом API с добавленными параметрами запроса, включая имя метода обратного вызова.Поскольку сценарии могут быть загружены из любого домена, это работает, но ограничивает вас запросами GET.Удаленный хост возвращает тело скрипта, который является обратным вызовом, вызванным в результирующем объекте javascript.jQuery обычно создает функцию обратного вызова для вас и вызывает функцию анонимного обратного вызова, которую вы предоставляете в параметрах метода getJSON.

Появляются стандарты, CORS и UMP (см. Также сравнение ), которые поддерживаются некоторыми браузерами, но не стандартизированными способами (читайте, IE делает это иначе).Есть плагинов для частичной поддержки тех браузеров, которые поддерживают CORS.Понятия не имею, насколько хорошо они работают, и они не будут работать, если браузер не поддерживает это.

1 голос
/ 23 мая 2011

Другие ответы не совсем верны.Это возможно, если у вас есть контроль над сервером.

См .: W3C - Распределение ресурсов между источниками http://www.w3.org/TR/cors/

По сути, клиент отправляет HTTP-запрос OPTIONS «перед полетом» и, если с сервера получен правильный ответ, это продолжается с его регулярными операциями.(Есть много примеров в Интернете ... Если я не понадоблюсь, я не буду вдаваться в подробности).

Я понимаю, что это может работать не во всех сценариях (например, я не уверен, поддерживает ли IE5 / 5.5 это или нет ... но я верю, что IE6 поддерживает) ... но если вы работаетев приложении HTML5, и у вас есть контроль над сервером, это может быть для вас возможностью.

ПРИМЕЧАНИЕ: Просто в стороне - учитывая опцию, я бы предпочел JSONP, конечно.Меньше ошибаться.

РЕДАКТИРОВАТЬ: Кажется, здесь много путаницы, поэтому позвольте мне привести пример того, как можно сделать это с помощью .NET / WCF (я думаю, что некоторые из этого пришли из статьигде-то, и другие его части были разработаны собственными силами ... поэтому, если некоторые из них были получены откуда-то еще, я заранее прошу прощения за то, что не дал должную оценку):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace YourNamespaceHere
{
    using System;
    using System.Web; 
    using System.Collections;

    public class CrossOriginModule : IHttpModule {
        public String ModuleName {
            get { return "CrossOriginModule"; } 
        }    

        public void Init(HttpApplication application) {
            application.BeginRequest += (new EventHandler(this.Application_BeginRequest));
        }

        private void Application_BeginRequest(Object source, EventArgs e) {
            HttpApplication application = (HttpApplication)source;
            HttpContext context = application.Context;
            CrossOriginHandler.SetAllowCrossSiteRequestOrigin(context);
        }

        public void Dispose() 
        {
        }
    }

   public class CrossOriginHandler : IHttpHandler
    {
        #region IHttpHandler Members
        public bool IsReusable
        {
            get { return true; }
        }

        public void ProcessRequest(HttpContext context)
        {
            //Clear the response (just in case)
            ClearResponse(context);

            //Checking the method
            switch (context.Request.HttpMethod.ToUpper())
            {
                //Cross-Origin preflight request
                case "OPTIONS":
                    //Set allowed method and headers
                    SetAllowCrossSiteRequestHeaders(context);
                    //Set allowed origin
                    //This happens for us with our module:
                    SetAllowCrossSiteRequestOrigin(context);
                    //End
                    context.Response.End();
                    break;

                default:
                    context.Response.Headers.Add("Allow", "OPTIONS");
                    context.Response.StatusCode = 405;
                    break;
            }

            context.ApplicationInstance.CompleteRequest();
        }
        #endregion

        #region Methods
        protected void ClearResponse(HttpContext context)
        {
            context.Response.ClearHeaders();
            context.Response.ClearContent();
            context.Response.Clear();
        }

        protected void SetNoCacheHeaders(HttpContext context)
        {
            context.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
            context.Response.Cache.SetValidUntilExpires(false);
            context.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
            context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
            context.Response.Cache.SetNoStore();
        }
        #endregion

        public static void SetAllowCrossSiteRequestHeaders(HttpContext context)
        {
            string requestMethod = context.Request.Headers["Access-Control-Request-Method"];

            context.Response.AppendHeader("Access-Control-Allow-Methods", "GET,POST");

            //We allow any custom headers
            string requestHeaders = context.Request.Headers["Access-Control-Request-Headers"];
            if (!String.IsNullOrEmpty(requestHeaders))
                context.Response.AppendHeader("Access-Control-Allow-Headers", requestHeaders);
        }

        public static void SetAllowCrossSiteRequestOrigin(HttpContext context)
        {
            string origin = context.Request.Headers["Origin"];
            if (!String.IsNullOrEmpty(origin))
                context.Response.AppendHeader("Access-Control-Allow-Origin", origin);
            else
                //This is necessary for Chrome/Safari actual request
                context.Response.AppendHeader("Access-Control-Allow-Origin", "*");
        }
    }
}

И в Интернете.конфиг:

  ...
  <system.webServer>
     ...
     <modules runAllManagedModulesForAllRequests="true">
     ...
           <add name="CrossOriginModule" preCondition="managedHandler" type="YOURNANMESPACEHERE.CrossOriginModule, ASSEMBLYNAME" />
    </modules>
    <handlers>
           <add name="CrossOrigin" verb="OPTIONS" path="*" type="YOURNAMESPACEHERE.CrossOriginHandler, ASSEMBLYNAME" />
    </handlers>
  </system.webServer>
0 голосов
/ 24 мая 2011

короче: JsonP - это междоменная техника, ограниченная GET-запросом.

0 голосов
/ 24 мая 2011
  1. test.php
<?php   fire query
        $row = array();
        while($queryresults){
          $row['id'] = '$queryresults['idfield']';
          $row['name'] = '$queryresults['namefield']';
          $row['marks'] = '$queryresults['marksfield']';
         $output[] = $row;
         }
echo json_encode( $output ); //json array
?>
  1. документ готов
$.getJSON('test.php?query=query,function(data) {    
    $.each(enq_data, function(i,data){
          $('.anydiv').append('<div class="row">'+data.id+data.name+data.marks+'</div>');
    });
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...