大家好,又见面了,我是你们的朋友全栈君。
摘要:Ajax 在 Web 2.0 时代起着非常重要的作用,然而有时因为同源策略(SOP)(俗称:跨域问题(cross domain)) 它的作用会受到限制。在本文中,将学习如何克服合作限制。本文以asmx方式搭建webservice作为测试用后端,给出完整的前后端调用解决方案、范例代码。
关键词: jquery ajax 跨域 webservice asmx cross-domain
0 问题分析
0.1 什么是跨域问题?
越来越多的网站需要相互协作。例如,在线房屋租赁网站需要谷歌地图的支持,以显示特定租赁房屋的位置。为了满足这样的需求,已经出现了各种各样的 mashup。mashup 是一种将不同供应商的数据或组件集成起来,使之更加有用或更用户化的Web应用程序。Mashup(或协作功能)被认为是Web 2.0的重要组成部分。
出人意料的是,将异步的 JavaScript、XML (Ajax)和mashup结合起来并不容易。由于浏览器施加的安全限制,让页面上的不同小部件彼此之间相互通信比较麻烦。通常,您可以通过在服务器端设置一个代理来解决此问题,该方法是不可扩展的。
问题详情见图:
0.2 问题解决思路
0.2.1 JSONP
JSONP 利用了 Web 页面可以从任何源码中下载脚本的能力。但 JSONP 有两个主要的限制:它与 Ajax 调用一样没有错误处理机制,并且脚本标记请求要使用 Get method,其中对长度有所限制。此方法非本文讨论重点,更多详情请自行搜索。
0.2.2 代理方法
思路请见图
本文使用vs2013作为集成开发环境(后简称IDE),理论上不受IDE限制。下文为测试项目,证明代理方案的可行性。
1 使用asmx建立asp.net webservice后端
1.1新建项目
VS2013->new project->Web Visual Studio2012->Asp.net Empty Web Application,取名“CrossDomain.Backend”,路径随意。
1.2 新建asmx
右击“CrossDomain.Backend”项目->新增->新项目->web->asmx->新增按钮
代码如下:
代码语言:javascript复制using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Web;
using System.Web.Script.Services;
using System.Web.Services;
namespace CrossDomain.Backend
{
/// <summary>
/// Summary description for WebService1
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
[System.Web.Script.Services.ScriptService]
public class WebService1 : System.Web.Services.WebService
{
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public int Sum(int a,int b)
{
Thread.Sleep(3000);
return a b;
}
}
}
1.3 小结。
后端建立完毕,可以自行调试。
2 建立前端
2.1 新建项目
VS2013->new project->Web Visual Studio2012->Asp.net Empty Web Application,取名“CrossDomain.Frontend”,路径随意。
2.2 建立文件架构
架构如下图
2.3 index.html代码如下:
代码语言:javascript复制<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>ajaxCallAsmxSample</title>
<script src="js/jquery-2.2.3.min.js" type="text/javascript"></script>
<script src="js/jquery.blockUI.js" type="text/javascript"></script>
<script src="js/index.js" type="text/javascript"></script>
</head>
<body>
a:<input type="text" id="a"><br>
b:<input type="text" id="b"><br>
<button id="ButtonAjaxRequest">AjaxRequest</button><br>
<label id="result"></label>
</body>
</html>
2.4 index.js代码如下
代码语言:javascript复制"use strict";
$(document).ready(function () {
$("#ButtonAjaxRequest").click(AjaxCallAsmx);
});
var dtStart;
var dtEnd;
var administrativeLevelStr;
var areaName;
var backEndUrl = "http://localhost:5633/WebService1.asmx/Sum";
var proxyUrl = "/DotNet/proxy.ashx?";
function AjaxCallAsmx() {
//显示遮罩并阻塞用户交互
$.blockUI({ message: '<h1><img src="images/loading.gif" .> Just a moment...</h1>' });
$.ajax({
type: "POST",
url: proxyUrl backEndUrl,
data: {
a: $("#a").val(),
b: $("#b").val()
},
dataType: "xml", //asmx默认返回xml格式数据
success: function (data, statusText, jqXHR) {
var x = $.parseXML(jqXHR.responseText);
var c = x.childNodes[0].textContent;
$("#result").html(c);
//去除遮罩
$.unblockUI();
}
});
}
请注意:
1 如果此处不使用代理(proxy),将出现常见的“跨域错误”,此处对错误案例不做列举,相信查阅到此文的读者都遇到过类似问题。
2 主要起到代理作用的是DotNet/proxy.ashx,和proxy.config文件;建议将这两个文件放在同一文件夹下。此文件最新版详见github,下载地址:https://github.com/Esri/resource-proxy。作者提供了:dotnet/java/php三种主流版本。
3 总结
文本对跨域问题的原因、分析、解决思路、思路实践案例进行了整理。留以方便读者少走弯路,同时自己备查。
4 参考文献
Wang Jiaye, Hu Changchun;利用客户端解决方案改进跨域通信; https://www.ibm.com/developerworks/cn/web/wa-crossdomaincomm/
JavaScript: Use a Web Proxy for Cross-Domain XMLHttpRequest Calls; https://developer.yahoo.com/javascript/howto-proxy.html
本范例代码下载地址:http://download.csdn.net/detail/fanrong1985/9513581
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/136314.html原文链接:https://javaforall.cn