常见浏览器跨域处理

2017-10-31  本文已影响0人  秀逼

在请求后端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", "*");  

*号代表所有域名都可以访问,可以换成需要处理的域名

方法二: 后端在header加上: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类型,请求方法,可以先抓一个请求成功的包看一下请求头

上一篇 下一篇

猜你喜欢

热点阅读