我正在为以下内容寻找最佳实践...
我有一个调用.asmx Web服务的JQuery脚本,但是在域外调用时无法加载,我理解当我将html移动到PhoneGap时会发生什么。
是使用JSONP的最佳/唯一解决方案吗?
我并没有停留在.asmx或jquery等等。打开任何您使用过的效果很好的想法。
只需要能够从html5调用服务器上的方法。 (并且html5应用程序不会脱机运行)。
谢谢!
答案 0 :(得分:0)
是JSONP是您问题的答案。 JSONP或“带填充的JSON”是一个JSON扩展,其中前缀被指定为调用本身的输入参数,并且只是为了克服XMLHttpRequest相同的域策略。
这两个链接可以帮助你。如果您有任何问题,请告诉我。
答案 1 :(得分:0)
要了解有关JSONP的更多信息,请点击here。
简单地说JSONP可以定义为(这是Remy Sharp博客的摘录)
JSONP是脚本标记注入,从服务器传递响应 到用户指定的功能
此link也可以帮助您找到问题的解决方案。
答案 2 :(得分:0)
如果您使用的是Phonegap,它会使用file://协议加载本地html文件。您的加载失败可能与same origin policy有关,并且不适用于file://协议。因此,使用file://协议加载您的html,您就可以进行跨浏览器调用。请查看this article以了解详情。另请查看Phonegap's docs about Domain whitelisting。
祝你好运!答案 3 :(得分:0)
我要说JSONP绝对是最好的方法,如果你需要在服务器端代码中允许OPTIONS
方法,你可以实现类似的代码。 (注意:此示例在技术上适用于MVC,但可以进行调整。)
public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
HttpContext.Current.Response.Cache.SetNoStore();
filterContext.RequestContext.HttpContext.Response.AppendHeader("Access-Control-Allow-Origin", "*");
string rqstMethod = HttpContext.Current.Request.Headers["Access-Control-Request-Method"];
if (rqstMethod == "OPTIONS" || rqstMethod == "POST")
{
filterContext.RequestContext.HttpContext.Response.AppendHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
filterContext.RequestContext.HttpContext.Response.AppendHeader("Access-Control-Allow-Headers", "X-Requested-With, Accept, Access-Control-Allow-Origin, Content-Type");
}
base.OnActionExecuting(filterContext);
}
}
[HttpGet]
[AllowCrossSiteJsonAttribute]
public JsonpResult CommunicateCard(CommunicateCardModel ccm)
{
return ModelState.IsValid
? this.ValidCommunicateCardBuilder(ccm)
: this.InvalidFormSummary(ccm);
}
旁注:这是我正在使用的JsonpResult。工作真棒。
namespace System.Web.Mvc
{
#region usings
using System;
using WebService.Attributes;
using WebService.Domain.Models;
using WebService.Exceptions;
using WebService.Models.ViewModels;
using Extensions;
using WebService.Utilities;
#endregion
public class JsonpResult : ActionResult
{
public Object Data { get; set; }
public string JsonCallback { get; set; }
public bool? Success { get; set; }
public override void ExecuteResult(ControllerContext context)
{
// Create a JsonResponse that we can Send out
// Check for the callback parameter
this.JsonCallback = context.HttpContext.Request["callback"];
// if the "callback" doesn't exist, we want to check for "jsoncallback"
if (string.IsNullOrEmpty(this.JsonCallback))
this.JsonCallback = context.HttpContext.Request["jsoncallback"];
// If we've made it this far, we know that the object sent is an
// object that we can serialize and Send back as valid JSON. We now
// need to wrap it in our JsonViewModel for consistancy. NOTE: We're
// using the AsList() extension method to ensure that we're
// returning an Array since our application (Sencha Touch) requires
// all data to be in array format.
if (!Data.GetType().IsGenericType)
Data = Data.AsList();
// Until now we the data is either an ERROR, or null
// if it's null, and the Data is not null, we set Success = true
// If Success is false, it's because we set it to false when we threw an error
// if that's the case, we keep it false for the client.
if (Success == null) Success = true;
var jsonViewModel = new JsonViewModel
{
results = this.Data,
// We know that Success is either True or False so we can
// safely cast the nullable bool to a bool.
success = (bool)this.Success
};
WriteOut(jsonViewModel, context);
}
/// <summary>
/// Write Out the JsonP Response to the Controller.
/// </summary>
/// <param name="jsonResponse">The unserialized object</param>
/// <param name="context">Controller Context</param>
private void WriteOut(JsonViewModel jsonResponse, ControllerContext context)
{
var response = context.HttpContext.Response;
response.ContentType = "application/javascript";
response.Write(JsonUtility.Serialize(jsonResponse, this.JsonCallback));
}
}
/// <summary>
/// extension methods for the controller to allow jsonp.
/// </summary>
public static class ContollerExtensions
{
public static JsonpResult Jsonp(this Controller controller, Object data)
{
return new JsonpResult { Data = data };
}
public static JsonpResult Jsonp(this Controller controller, Object data, bool success)
{
// We don't ever want to pass in a "true" success. We only want to
// know if it failed.
if (success)
{
return new JsonpResult { Data = data };
}
return new JsonpResult { Success = false, Data = data };
}
}
}