乱想-跨域

简介: 《ArcGIS API for JavaScript 开发教程》也告一段落,虽然很多还不是很清楚,但是心得还是有一点,我愿意将我的心得跟大家分享,喜欢和大家交流。 一个比较执着的技术男,一旦遇到了问题,他想的首先是解决这个问题,然后想的可能是为什么会遇到这样的问题,其次可能是解决此类问题能有几种方法,如果将这些都能理清,能说出个所以然来,我想这个技术男体会肯定颇深,我喜欢看这样的博文,尤其是一些关于什么什么的探究,或者运行机制,以至于本质,更厉害的博主直接就将一些底层的代码给剖出来,对于这样的博文或者博主,我只能望其项背,望洋兴叹。

《ArcGIS API for JavaScript 开发教程》也告一段落,虽然很多还不是很清楚,但是心得还是有一点,我愿意将我的心得跟大家分享,喜欢和大家交流。

一个比较执着的技术男,一旦遇到了问题,他想的首先是解决这个问题,然后想的可能是为什么会遇到这样的问题,其次可能是解决此类问题能有几种方法,如果将这些都能理清,能说出个所以然来,我想这个技术男体会肯定颇深,我喜欢看这样的博文,尤其是一些关于什么什么的探究,或者运行机制,以至于本质,更厉害的博主直接就将一些底层的代码给剖出来,对于这样的博文或者博主,我只能望其项背,望洋兴叹。我也喜欢写类似的博文,因为这些是自己体会所得,但是资质平庸,我只能泛泛而谈,算不上什么上乘之作。

话题要从跨域开始,我在写《ArcGIS API for JavaScript 开发教程》的时候,当向服务器发送XmlHttpRequest请求的时候,经常遇到这个错误,虽然我成不了什么能将问题剖根到底,或者一针见血的指出其缘由,但是我喜欢将这些记录下来,只希望在不断的碰壁中得到正确的解决之道。之所以有这个问题,原因很简单,浏览器只允许请求当前源(域名、协议、端口)的资源,当浏览器发现两个请求不在同一个域中的时候,就报错。浏览器这么规定,那我们也只能接受,还是那句话,改变不了的那就默默接受吧!

     浏览器没有错,因为浏览器出于安全考虑,是不允许JavaScript代码进行跨域操作。比如,liuyu.com站点中的Ajax只能访问liuyu.com站点下的资源,而不能跨域访问esrichina.com站点中的资源,这就是Ajax跨域问题。既然知道问题了,那么我们想的就是绕过跨域。

 

代理是一个解决方法,代理也是我用的最多的。

代理实际上起到了一个请求中转的作用,当A机器向C服务器请求的时候,A机器可以由B机器转发请求,然后A机器从代获取代理服务器B和C服务器的结果.代理也是一个Web服务器上运行的。常常使用动态网页(ASP.NET,PHP,JSP等)作为代理页面来作为这种中转请求的。上面这个关系应该一清二楚,毋庸置疑,代理在《ArcGIS API for JavaScript 开发教程》可以看到,这里就不多说了。

 

为什么在开发的时候可以直接使用Esri官网的在线的API?

页面在提交请求时,浏览器会进行Form身份验证(Form即为表单,每个页面都有一个Form标签),当向不同域获取数据时,浏览器认为这是不安全的,所以拒绝访问。   而标签script中的src请求远程服务数据时是不需要经过Form表单身份验证的,因为该标签并不包含在Form中,所以可以用此方法来请求不同域的数据。

 测试,建立一个新的js文件内容如下:

function Add (a, b) {

    return a + b;

}

 

alert(Add(1,2));

 

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

    <title>跨域测试</title>

    <script src="CrossTest.js" type="text/javascript"></script>

   <!-- <script src="http://localhost/CrossTest.js" type="text/javascript"></script>-->

</head>

<body>

 

</body>

</html>

 我们将这个JS文件部署在服务器上,这样就跟调用Esri的在线API类似。

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

    <title>跨域测试</title>

    <script src="CrossTest.js" type="text/javascript"></script>

   </head>

<body>

 

</body>

</html>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

    <title>跨域测试</title>

   

    <script src="http://localhost/CrossTest.js" type="text/javascript"></script>

</head>

<body>

 

</body>

</html>

 

可以看到,这两个都可以得到正确的结果.说明了script标签不受跨域影响,基于这个,我们也可以创建script标签,动态的来进行处理,如下:

 

 

 function
ScriptTag(src){

     var script = document.createElement('script');

         script.setAttribute("type","text/javascript");

         script.src = src;

         document.body.appendChild(script);

     }

     

     window.onload = function(){

         ScriptTag("http://localhost/CrossTest.js");

     }

 

 

 

 

 

http://www.cnblogs.com/chopper/archive/2012/03/24/2403945.html

JSONP,这个在使用esri.request的时候也常见。 

JSONP是JSON with Padding的略称。它是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)

JSONP通过一个回调函数来实现跨域的,当构建http请求参数的时候,如下:JSONPTest.ashx?callback=callback&a=3&b=4,callback是在客户端的一个函数,当服务器处理结束后,将有客户端这个函数进行回调处理,我们可以看下,esri.request这个请求的结构。

esri.request的结构大体如下:

  esri.request({

        url:“yoururl”,

        content:params,

        callbackParamName:"callback",

        load:function (result) {

 

        //省略

       

        },

        error:function (error) {

                  //省略

 

    });

}

 这个的意思不言而喻,当执行成功的话去处理load对象的函数,失败的话去处理error对应的函数。

我们可以自己去模拟这个过程,下面是服务器端代码:

 

public class JSONPTest : IHttpHandler

    {

 

     

            public void ProcessRequest(HttpContext context)

            {

                //获取回调函数名

                string callback = context.Request.QueryString["callback"];

 

                  JavaScriptSerializer js = new JavaScriptSerializer();

 

                  string a= context.Request.QueryString["a"];

 

                  string b = context.Request.QueryString["b"];

              

                //json数据

                StringBuilder Str= new StringBuilder();

                context.Response.ContentType = "application/json";

 

                js.Serialize(new { message = callback, result = Add(Convert.ToDouble(a), Convert.ToDouble(b)) }, Str);

                     context.Response.Write(callback+"("+Str+")");                  
            }

 

 

            public double Add(double a, double b)

            {

                return a + b;

            }

            public bool IsReusable

            {

                get

                {

                    return false;

                }

            }

        }

 

 客户端的代码,这里大家可以得到正确的值。

   
 function callback(data) {
         alert(data.result);
     }

 模拟是为了更好的了解,只在说明问题,当然你可能有更好的方法,现在很多框架都提供了JSONP这种方式,我们就没必要自己去折腾了。

相关文章
|
JSON JavaScript 前端开发
学习 同源策略,jsonp,跨域 随记
学习 同源策略,jsonp,跨域 随记
49 0
|
前端开发 Java 应用服务中间件
项目里面怎么解决跨域的?
项目里解决跨域的方法
|
前端开发 JavaScript
|
存储 前端开发 JavaScript
|
网络协议 Java 数据库连接
java后端跨域 配置 代码
java后端跨域 配置 代码
121 0
|
JSON 前端开发 数据格式
【实战晋级】理解跨域以及工作中跨域问题的处理 - 2 预检请求
本文是第2节,紧接上1节 【实战晋级】理解跨域以及工作中跨域问题的处理 - 1。
212 0
【实战晋级】理解跨域以及工作中跨域问题的处理 - 2 预检请求
|
前端开发 文件存储 数据安全/隐私保护
【小刘带你玩儿前端】什么是跨域以及如何解决?
现在的web项目,很多都是前后端分离,特别容易出现跨域问题
【小刘带你玩儿前端】什么是跨域以及如何解决?
又见跨域大坑....
又见跨域大坑....
265 0
|
JSON JavaScript 前端开发
跨域问题解决思路
在项目中经常遇到跨域问题,那么怎样解决跨域问题呢,下面提供几种解决跨域问题的解决思路。