常见浏览器跨域处理
老生常谈,不再赘述什么是跨域,概念请移步阮一峰博客,说现象,在请求后端api时经常会报一个错误:
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://xxxxxx.com' is therefore not allowed access.
方法一
后端在header加上
Access-Control-Allow-Origin: *
//php
header('Access-Control-Allow-Origin: *');
//java
response.setHeader("Access-Control-Allow-Origin", "*");
*号代表所有域名都可以访问,可以换成需要处理的域名
方法二
jsonp,同样后端配合处理,简单说下原理,浏览器请求<script>脚本是没有跨域的限制,通过动态创建script标签请求目标地址就可以拿到返回的json(前提后端返回的是个json)数据,此时浏览器会将这个json当作脚本来执行,结果是报语法错误,所以还要另外做些处理,在请求的地址后面加个参数,让后端在处理请求时判断,如果带了这个参数就将这个参数的值和json做个拼接param+(jsonstring),其实就可以理解为返回的就是以参数值为方法名json对象为参数的一个js方法执行脚本,然而拿到数据前浏览器端已经定义好一个这个参数同名方法,处理这个传进来的json方法,github上有一些jsonp的实现,jq和zepto都有,jsonp和ajax是两种本质不同的形式
$.ajax({
type: "get",
async: false,
url: "url",
dataType: "jsonp",
jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
jsonpCallback:"flightHandler",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据
success: function(res){
console.log(res)
},
error: function(e){
console.log(e)
}
})
方法三
服务器代理请求,有些场景下提供数据的接口不能更改又不支持jsonp,这个时候可以写个接口B去请求那个跨域的接口A,此时接口B的服务端相当于接口A的客户端单独发送http请求,拿到数据后再返回给自己的客户端
//node服务端
var app = express()
var axios = require('axios')
var apiRoutes = express.Router()
apiRoutes.get('/proxy', function (req, res) {
var url = 'https://www.a.com/api/a'
axios.get(url, {
headers: {
referer: 'https://www.a.com/',
host: 'www.a.com'
},
params: req.query
}).then((response) => {
res.json(response.data)
}).catch((e) => {
console.log(e)
})
})
app.use('/api', apiRoutes)
//客户端
var axios = require('axios')
const url = "/api/proxy"
let query = params;//请求参数
axios.post(proxyUrl, query).then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
代理请求的时候要注意请求参数和请求头的设置,比如Content-Type类型,请求方法,可以先抓一个请求成功的包看一下请求头
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。