什么是跨域?
跨域,不同域名之间的通信,就是跨域。如何区分是否是跨域呢,请看下面的例子。
以 http://www.a.com:8888 为例
@@@
产生跨域的情况
@@
一个网站的网址组成包括协议名,子域名,主域名,端口号
@一个网站的网址组成包括协议名,子域名,主域名,端口号。比如
https://github.com/
,其中https是协议名,www是子域名,github是主域名,端口号是80,当在在页面中从一个url请求数据时,如果这个url的协议名、子域名、主域名、端口号任意一个有一个不同,就会产生跨域问题。
即使是在
http://localhost:80/
页面请求
http://127.0.0.1:80/
也会有跨域问题
方案二 ———同主域,不同子域。
很简单,只要设置子域的域名指向父域就好。
例: http://s1.a.com http://a.com
修改http://s1.a.com 的域名指向 document.domain = "a.com";
方案一 ———通过JSONP跨域
1,所以 JSONP 的理念就是,我和服务端约定好一个函数名,当我请求文件的时候,服务端返回一段 JavaScript。这段 JavaScript 调用了我们约定好的函数,并且将数据当做参数传入。非常巧合的一点(其实并不是),JSON 的数据格式和 JavaScript 语言里对象的格式正好相同。所以在我们约定的函数里面可以直接使用这个对象。
你需要获取数据的页面 index.html:
<script>
function
getWeather(data) {
console
.log(data);
}
</script>
<script
src
=
"http://x.y.com/xx.js"
>
http://x.y.com/xx.js
文件内容:
getWeather({
"城市"
:
"北京"
,
"天气"
:
"大雾"
});
我们可以看到,在我们定义了
getWeather(data)
这个函数后,直接载入了 xx.js。
在这个脚本中,执行了
getWeather
函数,并传入了一个对象。然后我们在这个函数中将这个对象输出到 console 中。
这就是整个 JSONP 的流程。
2,
jsonp是JSON with padding的简写,看起来与json差不多,但是包含在函数调用中的json,利用动态script元素来使用(具有src属性的如img,iframe,srcipt都不受同源策略的影响)。该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。
如果使用jquery,可以在type为get的时候dataType设为jsonp,就可以了。
$.ajax({
url:
'http://www.qdaily.com/get_user_and_radar.json?winWidth=1280&winHeight=800'
,
type
:
'get'
,
dataType:
'jsonp'
,
data
: {},
})
.done(
function
(data) {
console.
log
(
data
.
status
);
})
看一个运行成功的实例:
$.ajax({
url:
'http://localhost:8000/remote/remote.js'
,
type:
'get'
,
dataType:
'jsonp'
,
jsonp:
'back'
,
jsonpCallback:
"haddleData"
,
data: {}, })
.done(
function
(data) {
console
.log(data.status);
})
//这段程序运行在8080端口的
remote.js作为远端其中写了句
haddleData
({
"status"
:true,subscribes:[
"12"
,
"23"
]})
对于大部分js初学者,大多使用jquery,而对原生不太熟悉(譬如我。。。好惭愧)。但是须知,ajax和jsonp其实本质上是不同的东西,ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加<script>标签来调用服务器提供的js脚本。
原生js的jsonp简单实现:
<
script
>
function
haddleData
(data){
console
.log(data.status);
}</
script
>
<
script
type=
"text/javascript"
src=
"http://localhost:8000/remote/remote.js"
></
script
>
当然有多个本地函数需要处理的时候,加上回调函数名才是方便的,像这样:
<
script
type=
"text/javascript"
src=
"http://localhost:8000/remote/remote.js?callback=haddleData"
></
script
>
【总结下jsonp】:
- 优点:
简单,函数回调在本地处理;
- 缺点:
1、安全性(存在注入漏洞,如CSRF,XSS);
2、如果出现错误,不会像http请求那样有状态码;
3、只能使用get请求;