1、什么是跨域
指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对javacript施加的安全限制
2、怎么处理跨域
方法一:代理(后台做的)
指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对javacript施加的安全限制
例如www.123.com/index.html需要调用www.456.com/server.php . 可以写一个接口www.123.com/server.php .由这个接口在后端去调用www.456.com/server.php 并且拿到返回值,然后在返回给index.html 。这就是一个代理的模式。相当于绕过了浏览器,自然就不存在跨域问题。
例如www.123.com/index.html需要调用www.456.com/server.php . 可以写一个接口www.123.com/server.php .由这个接口在后端去调用www.456.com/server.php 并且拿到返回值,然后在返回给index.html 。这就是一个代理的模式。相当于绕过了浏览器,自然就不存在跨域问题。
方法二:jsonp(重点,但是只支持get方式请求。不支持post方式。)
方法三:XHR2(了解即可)
jsonp原理和步骤:
<script>标签
src的作用 : 加载(包含指定的外部文件)
可以跨域包含
被包含的资源可以是任何类型的文件(可以是txt,php等)
他只关注被包含的文件的内容是否是合法的JS
原理
定义函数
包含外部文件,在被包含的文件中执行调用定义好的函数
参数的(数据)的实现
问题:包含就调用,通过动态创建<script>实现按需调用
问题:包含动态文件时可以通过一个接口实现按需生成调用函数名称
JSONP : JSON with Padding
1.script标签
2.用script标签加载资源是没有跨域问题的
在资源加载进来之前定义好一个函数,这个函数接收一个参数(数据),函数里面利用这个参数做一些事情
然后需要的时候通过script标签加载对应远程文件资源,当远程的文件资源被加载进来的时候,就会去执行我们前面定义好的函数,并且把数据当作这个函数的参数传入进去
普通的ajax请求只能拿本地的文件:这个例子是没有问题的。
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>无标题文档</title>
<script>
window.onload = function() {
var oBtn = document.getElementById('btn');
oBtn.onclick = function() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if ( xhr.status == 200 ) {
alert( xhr.responseText );
}
}
}
xhr.open('get', '1.txt', true);
xhr.send();
}
}
</script>
</head>
<body>
<input type="button" value="按钮" id="btn" />
</body>
</html>
但是还用这个方法获取远程的数据(豆瓣api:
http://api.douban.com/book/subjects?q=javascript&alt=json&max-results=1
)就拿不到数据了,因为这个就是跨域:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>无标题文档</title>
<script>
window.onload = function() {
//ajax跨域请求限制
var oBtn = document.getElementById('btn');
oBtn.onclick = function() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if ( xhr.status == 200 ) {
alert( xhr.responseText );
}
}
}
xhr.open('get', 'http://api.douban.com/book/subjects?q=javascript&alt=json&max-results=1', true);
xhr.send();
}
}
</script>
</head>
<body>
<input type="button" value="按钮" id="btn" />
XMLHttpRequest cannot load http://api.douban.com/book/subjects?q=javascript&alt=json&max-results=1. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.
<p>
跨域:跨域名
一个域名下的文件去请求了和他不一样的域名下的资源文件,那么就会产生跨域请求
</p>
</body>
</html>
那怎么办呢?联想一下:
以前我们想用jq里面的方法,只要链接一个地址,这个jq文件可以在本地,也可以在远程服务器下面。
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>无标题文档</title>
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script>
</script>
</head>
<body>
JSONP : JSON with Padding
1.script标签
2.用script标签加载资源是没有跨域问题的
</body>
</html>
利用这个方法,我们就用创建
script
节点的方式来链接外部资源
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>无标题文档</title>
<script>
function fn(data) {
alert(data);
}
</script>
<script src="2.txt"></script>
<script>
//alert(a);
</script>
</head>
<body>
</body>
</html>
外部准备一个2.txt文件:
fn([1,2,3]);
发现我们可以拿到数据。
当然,这个数据是想点击的时候再使用,我们就动态加载标签即可:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>无标题文档</title>
<script>
function fn(data) {
alert(data);
}
</script>
<!--<script src="2.txt"></script>-->
<script>
window.onload = function() {
var oBtn = document.getElementById('btn');
oBtn.onclick = function() {
//当按钮点击的时候再去加载远程资源,让他执行
var oScript = document.createElement('script');
oScript.src = '2.txt';
document.body.appendChild(oScript);
}
}
</script>
</head>
<body>
<input type="button" id="btn" value="按钮" />
JSONP : JSON with Padding
1.script标签
2.用script标签加载资源是没有跨域问题的
在资源加载进来之前定义好一个函数,这个函数接收一个参数(数据),函数里面利用这个参数做一些事情
然后需要的时候通过script标签加载对应远程文件资源,当远程的文件资源被加载进来的时候,就会去执行我们前面定义好的函数,并且把数据当作这个函数的参数传入进去
</body>
</html>
我们可以再写一个php文件,传送数据:点击按钮,加载数据插入到li里面
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>无标题文档</title>
<script>
function fn(data) {
var oUl1 = document.getElementById('ul1');
var html = '';
for (var i=0; i<data.length; i++) {
html += '<li>'+data[i]+'</li>';
}
oUl1.innerHTML = html;
}
</script>
<script>
window.onload = function() {
var oBtn1 = document.getElementById('btn1');
oBtn1.onclick = function() {
var oScript = document.createElement('script');
oScript.src = 'getData.php';
document.body.appendChild(oScript);
}
}
</script>
</head>
<body>
<input type="button" id="btn1" value="按钮" />
<ul id="ul1"></ul>
</body>
</html>
getData.php文件内容:
再一步完善:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>无标题文档</title>
<script>
function fn1(data) {
var oUl1 = document.getElementById('ul1');
var html = '';
for (var i=0; i<data.length; i++) {
html += '<li>'+data[i]+'</li>';
}
oUl1.innerHTML = html;
}
function fn2(data) {
var oUl2 = document.getElementById('ul2');
var html = '';
for (var i=0; i<data.length; i++) {
html += '<li>'+data[i]+'</li>';
}
oUl2.innerHTML = html;
}
function fn3(data) {
var oUl3 = document.getElementById('ul3');
var html = '';
for (var i=0; i<data.length; i++) {
html += '<li>'+data[i]+'</li>';
}
oUl3.innerHTML = html;
}
</script>
<script>
window.onload = function() {
var oBtn1 = document.getElementById('btn1');
var oBtn2 = document.getElementById('btn2');
oBtn1.onclick = function() {
var oScript = document.createElement('script');
oScript.src = 'getData.php?callback=fn1';
document.body.appendChild(oScript);
}
var oBtn2 = document.getElementById('btn2');
oBtn2.onclick = function() {
var oScript = document.createElement('script');
oScript.src = 'getData.php?t=str&callback=fn2';
document.body.appendChild(oScript);
}
var oBtn3 = document.getElementById('btn3');
oBtn3.onclick = function() {
var oScript = document.createElement('script');
oScript.src = 'getData.php?callback=fn3';
document.body.appendChild(oScript);
}
}
</script>
</head>
<body>
<input type="button" id="btn1" value="加载数字" />
<ul id="ul1"></ul>
<input type="button" id="btn2" value="加载字母" />
<ul id="ul2"></ul>
<input type="button" id="btn3" value="加载字母" />
<ul id="ul3"></ul>
</body>
</html>
处理文件:
<?php
$t = isset($_GET['t']) ? $_GET['t'] : 'num';
$callback = isset($_GET['callback']) ? $_GET['callback'] : 'fn1';
$arr1 = array('111111','22222222','33333333','4444444','555555555555555555555');
$arr2 = array('aaaaaaaaaaaa','bbbbbbbb','cccccccccccc','ddddddddd','eeeeeeeeeeee');
if ($t == 'num') {
$data = json_encode($arr1);
} else {
$data = json_encode($arr2);
}
echo $callback.'('.$data.');';
案例一:百度搜索提升框
打开百度,我们一边打字会发现出现相关的关键字供你查看:这个时候打开网络查看,发现这个数据是通过ajax的方式动态加载过来的,还能找到这个域名请求的地址:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>无标题文档</title>
<style>
#q {width: 300px; height: 30px; padding: 5px; border:1px solid #f90; font-size: 16px;}
#ul1 {border:1px solid #f90; width: 310px; margin: 0;padding: 0; display: none;}
li a { line-height: 30px; padding: 5px; text-decoration: none; color: black; display: block;}
li a:hover{ background: #f90; color: white; }
</style>
<script>
function fn(data) {
var oUl = document.getElementById('ul1');
var html = '';
if (data.s.length) {
oUl.style.display = 'block';
for (var i=0; i<data.s.length; i++) {
html += '<li><a target="_blank" href="http://www.baidu.com/s?wd='+data.s[i]+'">'+ data.s[i] +'</a></li>';
}
oUl.innerHTML = html;
} else {
oUl.style.display = 'none';
}
}
window.onload = function() {
var oQ = document.getElementById('q');
var oUl = document.getElementById('ul1');
oQ.onkeyup = function() {
if ( this.value != '' ) {
var oScript = document.createElement('script');
oScript.src = 'http://suggestion.baidu.com/su?wd='+this.value+'&cb=fn';
document.body.appendChild(oScript);
} else {
oUl.style.display = 'none';
}
}
}
</script>
</head>
<body>
<input type="text" id="q" />
<ul id="ul1"></ul>
</body>
</html>
效果:
案例二:豆瓣网查询书籍
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>无标题文档</title>
<style>
#q {width: 300px; height: 30px; padding: 5px; border:1px solid #f90; font-size: 16px;}
dl {border-bottom: 1px dotted #000;}
dt {font-weight: bold;}
</style>
<script>
function fn1(data) {
var oMsg = document.getElementById('msg');
var oList = document.getElementById('list');
console.log(data);
oMsg.innerHTML = data.title.$t + ' : ' + data['opensearch:totalResults'].$t;
var aEntry = data.entry;
var html = '';
for (var i=0; i<aEntry.length; i++) {
html += '<dl><dt>'+ aEntry[i].title.$t +'</dt><dd><img src="'+ aEntry[i].link[2]['@href'] +'" /></dd></dl>';
}
oList.innerHTML = html;
}
window.onload = function() {
var oQ = document.getElementById('q');
var oBtn = document.getElementById('btn');
var oMsg = document.getElementById('msg');
var oList = document.getElementById('list');
oBtn.onclick = function() {
if ( oQ.value != '' ) {
var oScript = document.createElement('script');
oScript.src = 'http://api.douban.com/book/subjects?q='+oQ.value+'&alt=xd&callback=fn1';
document.body.appendChild(oScript);
}
//http://api.douban.com/book/subjects?q='+oQ.value+'&alt=xd&callback=fn1&start-index=(当前页*每页显示的条数)&max-results=10(每页显示的条数)
}
}
</script>
</head>
<body>
http://www.douban.com/service/apidoc/reference/
<input type="text" id="q" /><input type="button" id="btn" value="搜索" />
<p id="msg"></p>
<hr />
<div id="list"></div>
</body>
</html>
天天头条数据接口:
https://toutiao.eastday.com/toutiao_h5/RefreshJP?type=toutiao&picnewsnum=1&jsonpcallback=fn1
接口分享:
http://www.bejson.com/knownjson/webInterface/
案例三:聚合数据的使用方法。自己动手
http://www.cnblogs.com/annie00/p/6112487.html
其他jsonp的说明和教程(jq里面的$.ajax()也可以实现跨域):
http://www.360doc.com/content/14/1030/09/5054188_421070813.shtml
http://www.cnblogs.com/ccode/p/4871853.html
http://www.jb51.net/article/46463.htm
jsonp的封装方法:
http://blog.csdn.net/u013830811/article/details/52718664
http://blog.csdn.net/liusaint1992/article/details/50959571
指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对javacript施加的安全限制