什么是跨域:
- 浏览器在发送Ajax请求时,只接收同域服务器响应的数据资源;那么什么才算同域呢?很简单,协议、域名、端口全部相同才算同一域下,三个条件有一个不一致,都不算同域,既跨域。
同源策略,也叫跨域禁止策略
- 阻止从一个域上加载的脚本,获取或操作另一个域上的资源;
实际操作:
-
启动两个端口的服务器:
-
访问8000端口的服务器获取页面,页面中使用 ajax 向9000端口的服务器发送请求;
jsonp
- Web页面上调用js文件时则不受是否跨域的影响 (不仅如此,我们还发现凡是拥有"src"这个属性的标签都拥有跨域的能力,比如script、img、iframe); src 的能力就是把远程的数据资源加载到本地(图片、JS代码等);
如何使用JSONP
-
就是在远程服务器上设法动态的把数据装进js格式的文本代码段中,供客户端调用和进一步处理; 在前台通过动态添加script标签及src属性,表面看上去与ajax极为相似,但是,这和ajax并没有任何关系; 为了便于使用及交流,逐渐形成了一种 非正式传输协议,人们把它称作 JSONP ;
-
该协议的一个要点就是允许用户传递一个callback参数给服务端, 然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据, 这样客户端就可以随意定制自己的函数来自动处理返回数据了。
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
<!-- jsonp的核心:利用src的属性发送请求,服务器返回js代码调用前端页面写好的函数 -->
<script>
function backData(data){
alert(data);
}
</script>
<!-- 返回的是:backData(123) -->
<!-- 1.核心写法 -->
<script src="http://127.0.0.1:9000/">
// <!-- 2.函数名传进去在后台就不用知道你外面的函数名了 -->
// <!-- <script src="http://127.0.0.1:9000/getjson?callback=backData"> -->
</script>
</html>
8000服务器:
var fs = require('fs');
var url = require('url');
var http = require('http');
var server = http.createServer();
server.listen(8000, function () {
console.log('8000启动成功!')
})
server.on('request', function (req, res) {
var urls = url.parse(req.url, true);
if (req.method == 'GET') {
if (urls.pathname == '/') {
} else if (urls.pathname == '/gets') {
res.end('');
} else {
fs.readFile('.' + urls.pathname, function (err, data_str) {
if (!err) {
res.end(data_str);
} else {
res.end('')
}
})
}
} else if (req.method == 'POST') {
}
})
9000服务器
var fs = require('fs');
var url = require('url');
var http = require('http');
var server = http.createServer();
server.listen(9000, function () {
console.log('9000启动成功!')
})
server.on('request', function (req, res) {
var urls = url.parse(req.url, true);
if (req.method == 'GET') {
//1.核心写法
if (urls.pathname == '/') {
var num = "123";
// var num = "文字"; 也不行
res.end('backData('+ num+')');
} else if (urls.pathname == '/gets') {
res.end('浏览器显示出来了');
//2.函数名不用知道
}else if(urls.pathname == '/getjson'){
var str ='函数名后台我不用知道';
//str没有输出
// res.end(urls.query.callback+'('+str+')');
//url可以达到函数名 因为它是通过url地址传过来的
res.end(urls.query.callback+'('+'123'+')');
} else {
fs.readFile('.' + urls.pathname, function (err, data_str) {
if (!err) {
res.end(data_str);
} else {
res.end('');
}
})
}
} else if (req.method == 'POST') {
//post请求
if (urls.pathname == '/posts') {
var d = '';
req.on('data', function (post_data) {
d += post_data;
})
req.on('end', function () {
var obj = require('querystring').parse(d);
if (obj.name == 'admin') {
res.end('repeat')
} else {
res.end('norepeat')
}
})
}
}
})
第二种:跨域资源共享( CORS)机制
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="button"value="按钮" >
</body>
<script>
document.getElementsByTagName('input')[0].onclick = function(){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState== 4 ){
alert(xhr.responseText);
}
}
//简单的请求
// xhr.open('get','http://127.0.0.1:9000/getcors');
//请求方法:
xhr.open('delete','http://127.0.0.1:9000/getcors');
//
// xhr.setRequestHeader('get','http://127.0.0.1:9000/getcors');
//请求头
// xhr.setRequestHeader('kkkkk','http://127.0.0.1:9000/getcors');
xhr.send();
}
</script>
</html>
8000:服务器
var fs = require('fs');
var url = require('url');
var http = require('http');
var server = http.createServer();
server.listen(8000, function () {
console.log('8000启动成功!')
})
server.on('request', function (req, res) {
var urls = url.parse(req.url, true);
if (req.method == 'GET') {
if (urls.pathname == '/') {
} else if (urls.pathname == '/gets') {
res.end('');
} else {
fs.readFile('.' + urls.pathname, function (err, data_str) {
if (!err) {
res.end(data_str);
} else {
res.end('')
}
})
}
} else if (req.method == 'POST') {
}
})
9000:服务器
var fs = require('fs');
var url = require('url');
var http = require('http');
var server = http.createServer();
//都需要有的
server.listen(9000, function () {
console.log('9000启动成功!')
})
server.on('request', function (req, res) {
var urls = url.parse(req.url, true);
//写到这里:
res.setHeader('Access-Control-Allow-Origin','http://127.0.0.1:8000');
if (req.method == 'GET') {
if (urls.pathname == '/') {
} else if (urls.pathname == '/getcors') {
//返回之前就加请求头
// res.setHeader('Access-Control-Allow-Origin','http://127.0.0.1:8000');
res.end('123456789');
}else {
fs.readFile('.' + urls.pathname, function (err, data_str) {
if (!err) {
res.end(data_str);
} else {
res.end('');
}
})
}
} else if (req.method == 'POST') {
//post请求
if (urls.pathname == '/posts') {
var d = '';
req.on('data', function (post_data) {
d += post_data;
})
req.on('end', function () {
var obj = require('querystring').parse(d);
if (obj.name == 'admin') {
res.end('repeat')
} else {
res.end('norepeat')
}
})
}
}else if(req.method == 'OPTIONS'){
//是否允许你发什么类型的请求头过来
//'Access-Control-Allow-Headers' ,'DELETE还有很多可以加'
// res.setHeader('Access-Control-Allow-Origin','http://127.0.0.1:8000');
res.setHeader('Access-Control-Allow-Methods','DELETE');
res.end('');
}else if(req.method == 'DELETE'){
res.end('1335881694');
}else{
}
})