什么是跨域技术?
比如我们现在本机地址是127.0.0.1 我们想请求127.0.0.2上的数据
我们无法使用ajax来实现这样的跨域的数据请求
浏览器会阻止对ip地址不同,或者端口号不同的数据请求。
此时我们必须要进行请求,就是跨域技术。
所以这里介绍几种常见的跨域方法
一、JSONP跨域
JSONP叫做JSON 和 padding
- 我们写一个接口,这个接口不是一个JSON,而是一个语句,这个语句是
函数的调用
。 在页面上,我们定义一个函数,然后用script标签引入这个语句,执行这个语句。
此时数据就通过函数的实参和形参的结合,传入了页面。
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
// 定义函数
function haha(info){
console.log(info);
}
</script>
// 创建script标签
<script src="http://127.0.0.2/a.txt"></script>
</body>
</html>- script没有跨域限制的,可以轻松src引入其他ip地址的js文件。
- 关于script的相关知识
script标签仅在创建的时候发生HTTP请求 更改src属性时是不发出请求的
所以script标签是一次性的,用完删掉她再用时再重新创建
JQuery中写法:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<button>按我发出请求</button>
<script src="jquery-3.3.1.min.js"></script>
<script>
$("button").click(function(){
$.ajax({
"dataType" : "JSONP" ,
"url" : "http://127.0.0.2/a.php?callback=?",
"success" : function(data){
console.log(data);
}
})
});
</script>
</body>
</html>
小总结:
- 请求一个接口,接口中的数据形式是一个函数的调用
- 接口中是函数的调用所以在本地我们要创建相应的函数
需要注意的是:在JSONP跨域时,函数是没有声明提升的,所以函数的定义必须写在script标签创建之前 - script标签没有跨域限制,所以我们通过src引入其他ip地址的文件实现跨域请求数据
需要注意:script标签是在创建的那一刻调用,调用一次后就失效了,想再次使用必须重新创建
所以我们最好要动态的生成script标签,上树过后立即下数
二、CORS跨域
这是最最简单的跨域方法,但是IE8才开始兼容。
火狐MDN的解释
重点
:
跨域资源共享( CORS , cross-origin resource sharing)机制允许 Web 应用服务器进行跨域访问控制,
从而使跨域数据传输得以安全进行。
浏览器支持在 API 容器中(例如 XMLHttpRequest 或 Fetch )使用 CORS,以降低跨域 HTTP 请求所带来的风险。
说白了,就是在HTTP下行响应的头部加上了一些头部:
我们一般:就加Access-Control-Allow-Oringin值为*
以node.js为服务器
所以我们的express代码加一行代码:app.get("/a" , function(req,res){
res.setHeader("Access-Control-Allow-Origin" , "*");
res.json({"a" : 100})
});
表示允许来自任何域名的请求。
此时我们就能无脑跨域了!因为后端有一个允许的*,表示允许任何域的请求。
$.get("http://127.0.0.1:3000/a", function(data){
console.log(data);
})
三、代理跨域
比如用PHP实现(了解即可)这就代理到了百度首页:
echo file_get_contents("http://www.baidu.com");
代理跨域就是通过后台的命令,因为服务器与服务器之间没有跨域限制,实现跨域。
以webpack为例,详细说一下代理跨域:
你的webpack.config.js中添加配置const path = require('path');
module.exports = {
entry: "./www/app/main.js",
output: {
path: path.resolve(__dirname, "www/dist"),
filename: "bundle.js",
publicPath: "/xuni/"
},
mode : "development",
module: {
rules: [
{
test: /\.js$/,
include: [
path.resolve(__dirname, "www/app")
],
exclude: [
path.resolve(__dirname, "node_modules")
],
loader: "babel-loader",
options: {
presets: ["es2015","react"],
plugins: ["transform-object-rest-spread"]
}
}
]
},
// 就这里就这里 我的服务端放在了3000端口
devServer: {
proxy: {
"/api": {
target: 'http://127.0.0.1:3000/',
changeOrigin: true,
pathRewrite: {
'^/api': '/'
}
}
}
}
}
这配置是从webpack官网上来的,你就拿来主义即可。
我的服务端放在了3000端口,我的前端在8000端口
现在加上了上边的配置后,我在3000端口下的数据,将会被代理到8000/api下
这样从本质上讲,因为数据已经被代理到了8000端口下,我们在前段请求数据的时候,就已经不是跨域请求了。