如何进行ajax跨域访问

来源:互联网 发布:2017 博士 知乎 编辑:程序博客网 时间:2024/06/06 19:15

一.什么算跨域

我们先回顾一下域名地址的组成:
http://www.baidu.com:80/script/ajax.js
其中http://(协议号)
www(子域名)
google(主域名)
80(端口)
script/ajax.js (请求的地址)
当协议、子域名、主域名、端口号中任意一各不相同时,都算不同的“域”。不同的域之间相互请求资源,就叫“跨域”。 (自参考自)

二.跨域出现的原因

这个是浏览器做得限制,因为如果用跨域访问会造成不安全,可以不进行CSRF攻击(有关介绍](https://www.zhihu.com/question/26379635))

三.解决办法

目前有三种解决办法:

  1. 用代理服务器代理
  2. 使用jsonp
  3. 服务端设置Request Header头中Access-Control-Allow-Origin为指定可获取数据的域名

详细用法:

1.使用代理服务器:

原理:可以先使用自己的服务器用http请求访问其他服务器的资源,前端用ajax来访自己的服务器。

2.使用JSONP

原理:在同源策略下,在某个服务器下的页面是无法获取到该服务器以外的数据的,但img、iframe、script等标签是个例外,这些标签可以通过src属性请求到其他服务器上的数据。利用script标签的开放策略,我们可以实现跨域请求数据,当然,也需要服务端的配合。当我们正常地请求一个JSON数据的时候,服务端返回的是一串JSON类型的数据,而我们使用JSONP模式来请求数据的时候,服务端返回的是一段可执行的JavaScript代码。
举个例子假设从服务器(http://www.a.com/user?id=123)获取一个数据如下:

{"id": 123, "name" : 张三, "age": 17}

那么,使用JSONP方式请求(http://www.a.com/user?id=123&callback=foo)的数据将会是如下:

foo({"id": 123, "name" : 张三, "age": 17});

当然,如果服务端考虑得更加充分,返回的数据可能如下:

try{foo({"id": 123, "name" : 张三, "age": 17});}catch(e){}

这时候我们只要定义一个foo()函数,并动态地创建一个script标签,使其的src属性为http://www.a.com/user?id=123&callback=foo

做法:在jQuery中如何通过JSONP来跨域获取数据 :
第一种方法是在ajax函数中设置dataType为’jsonp’:

$.ajax({        dataType: 'jsonp',        url: 'http://www.a.com/user?id=123',        success: function(data){                //处理data数据        }});

第二种方法是利用getJSON来实现,只要在地址中加上callback=?参数即可:

$.getJSON('http://www.a.com/user?id=123&callback=?', function(data){        //处理data数据});或者//此时也可以在函数外定义foo方法function foo(data){        //处理data数据}$.getJSON('http://www.a.com/user?id=123&callback=foo');

JSONP的应用
JSONP在开放API中可以起到非常重要的作用,开放API是运用在开发者自己的应用上,而许多应用往往是在开发者的服务器上而不是在新浪微博的服务器上,因此跨域请求数据成为开发者们所需要解决的一大问题,广大开放平台应该实现对JSONP的支持,这一点新浪微博开放平台便做的非常好(虽然某些API里没有说明,但实际上是可以使用JSONP方式调用的)。
参考自
缺点:JSONP方法是一种非官方方法,而且这种方法只支持GET方式,不如POST方式安全。
即使使用jQuery的jsonp方法,type设为POST,也会自动变为GET

3.服务端设置Response Header头中Access-Control-Allow-Origin为指定可获取数据的域名

原理:通过自己的服务器响应首部字段加上一下响应字段

// 指定允许其他域名访问  'Access-Control-Allow-Origin:*';  // 响应类型  'Access-Control-Allow-Methods:POST';  // 响应头设置  'Access-Control-Allow-Headers:x-requested-with,content-type';做法:看我下一篇文章  
0 0
原创粉丝点击