解决跨域的三种方法
解决同源政策问题的几种方法
01-jsonp方法
- 在html文件里面写
<body>
<button>提交1</button>
<button>提交2</button>
<script>
// 要将全局作用的function也弄到其中
var btn = document.querySelector('button:first-child')
var btn1 = document.querySelector('button:nth-child(2)')
btn.onclick = function() {
jsonp({
url: 'http://localhost:3001/sever',
data: {
name: 'jinkai',
age: 20
},
success: function(data) {
console.log('btn1点击的')
console.log(data)
}
})
}
btn1.onclick = function() {
jsonp({
url: 'http://localhost:3001/sever',
data: {
},
success: function(data) {
console.log('btn2点击的')
console.log(data)
}
})
}
function jsonp(options) {
// 为了接收更多参数使用jsonp里面要加上data
var script = document.createElement('script')
var parms = ''
for (var atter in options.data) {
parms += '&' + atter + '=' + options.data[atter]
}
var fn = 'json' + Math.random().toString().replace('.', '')
script.src = options.url + '?callback=' + fn + parms
document.body.appendChild(script)
window[fn] = options.success
script.onload = function() {
document.body.removeChild(script)
}
}
</script>
</body>
</html>
- 在服务器s2里面填写
var express = require('express')
var path = require('path')
var app = express()
app.use(express.static(path.join(__dirname, 'public')))
app.get('/sever', function(req, res) {
// 将名字动态弄到了服务端
// const fname = req.query.callback
// const data = fname + '({name: "张三", age: "20"})'
// res.send(data)
//+服务器代码优化
// const fname = req.query.callback
// // 将json格式代码转化data
// const data = JSON.stringify({ name: "张三", age: "20" })
// const result = fname + '(' + data + ')'
// res.send(result)
// 看似上面代码很优秀,其实还有语法糖
// res提供了jsonp方法,其实原理就是上面代码(换汤不换药)
res.jsonp({ name: "张三", age: "20" })
})
- 总结:
- 1.jsonp封装函数就是新建script标签里面填写不同的src地址,然后被服务端接收,服务端发送函数调用。
- 2.了解了基本概念之后封装函数就会非常快!
- 3.Jsonp(JSON with Padding) 是 json 的一种"使用模式",可以让网页从别的域名(网站)那获取资料,即跨域读取数据。
02-CORS跨域方法
- 实现cors跨域很简单,ajax方法照常使用,但是要在不同域的服务端写下如下代码。
//注意:如果跨域请求中涉及到cookie信息传递,值不可以为*号 比如是具体的域名信息
res.header('Access-Control-Allow-Origin', 'http://localhost:3000')
// // 2.允许客户端使用哪些请求方法访问我
res.header('Access-Control-Allow-Methods', 'get,post')
- 假设有很多请求,都一一写哪两个设置的话重复代码太多了可以这样写
app.use((req, res, next) => {
// 1.允许哪些客户端访问我
// * 代表允许所有的客户端访问我
// 注意:如果跨域请求中涉及到cookie信息传递,值不可以为*号 比如是具体的域名信息
res.header('Access-Control-Allow-Origin', 'http://localhost:3000')
// 2.允许客户端使用哪些请求方法访问我
res.header('Access-Control-Allow-Methods', 'get,post')
// 允许客户端发送跨域请求时携带cookie信息
res.header('Access-Control-Allow-Credentials', true);
next();
})
- 总结:
- 1.打开设置的请求就可以跨域
- 2.记住每次打开的时候要重启服务器。
发现了一个奇怪的问题,就是每次写完CORS跨域再重新打开服务器,虽然能访问了。但是我如果删掉设置代码,还是能够跨域,浏览器的network里面还是可以看到
03-访问非同源数据的服务器端解决
- 这是间接的访问
例:(两个服务器s1,s2)在s1的app.js里面开启服务,s1里面的html文件访问本地的http://localhost:3000/s1 地址.但是本地s1里面有request第三方请求包。再通过服务器访问其他服务器就可以达到跨域效果。
要先安装request第三方包再s1里面(npm install request)
- s1服务器html文件
<button id="button">点击按钮</button>
<script src="/js/ajax.js"></script>
<script>
var btn = document.getElementById('button')
/// url地址写的是s1服务器,然后通过服务器来跨域
btn.onclick = function() {
ajax({
type: 'get',
url: 'http://localhost:3000/jianjie',
success: function(data) {
console.log(data)
}
})
}
</script>
- s1服务器
app.get('/jianjie', function(req, res) {
request('http://localhost:3001/cross', function(err, response, body) {
res.send(body)
})
// request里面的回调函数参数讲解:err 是错误信息
// response是一些请求的相关信息
// body是s2服务器发送的数据
})
- s2服务器
app.get('/cross', function(req, res) {
res.send('我是cross')
})
- 简单介绍一下流程
- s1服务器想要接收s2服务器里面的响应
- 所以s1服务器html文件通过ajax请求来访问s1服务器端
- s1服务器端再通过request来间接的响应s2服务器
简单的比较一下,总结一下
- CORS和JSONP比较(来源于:[阮一峰博客]http://www.ruanyifeng.com/blog/2016/04/cors.html)
CORS与JSONP的使用目的相同,但是比JSONP更强大。
JSONP只支持GET请求,CORS支持所有类型的HTTP请求。JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。 - 访问非同源数据的服务器端解决方案
记住这个是间接的访问!

浙公网安备 33010602011771号