jsonp跨域请求

我们通过ajax进行跨域请求的时候,请求发送过去,但是在接受返回数据的时候浏览器会进行拦截。

这是由于浏览器存在同源策略机制,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性。

比如我们在python中使用requests模块对一个天气api进行请求,然后传给前端,这个是可以的:

def req(request):
    response = requests.get('http://weatherapi.market.xiaomi.com/wtr-v2/weather?cityId=101121301')
    response.encoding='utf-8'
    print(response.text)
    return render(request,'req.html',{'result':response.text})

 

但是如果我们用原生js:XmlHttpRequest对该天气api发送请求得到结果时,却发生了错误

 1     <input type="button" value="获取数据" onclick="getContent();">
 2     <script>
 3         function getContent(){
 4             var xhr = new XMLHttpRequest();
 5             xhr.open('GET','http://weatherapi.market.xiaomi.com/wtr-v2/weather?cityId=101121301')
 6             xhr.onreadystatechange = function(){
 7                 console.log(xhr.responseText)
 8             }
 9             xhr.send()

 No 'Access-Control-allow-origin'

 

 

下面我们来看看两个方式的区别:

  第一种通过python从后台发送请求获得数据,没有经过浏览器,允许获得返回数据

  第二种我们通过浏览器直接给其他的域名发送请求,这个是不允许的

由于同源策略是浏览器的限制,所以请求的发送和响应是可以进行,只不过浏览器不接受罢了

解决方法:

 img、iframe、script等具有src属性的标签

 在src属性中写其他域名的文件,他不会出现跨域错误,但是需要注意的是,返回的必须是一个js文件格式,不然就会报错

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>后台获取结果</h1>
    {{ result }}
    <h1>js直接获取结果</h1>
    <div id="content"></div>
    <input type="button" value="获取数据" onclick="getContent();">
    <script>
        function getContent(){
            var tag = document.createElement('script');
            tag.src = "http://jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403";
            document.head.appendChild(tag);
            document.head.removeChild(tag);
        }
        function list(arg){
            console.log(arg)
        }
    </script>
</body>
</html>    

 

 如果使用jQuery的话就使用:

$.ajax({
            url : 'http://jxntv.cn/data/jmd-jxtv2.html',
            type:'post',
            dataType:'jsonp',
            jsonp:'callback',
            jsonpCallback:'list'
        })

 

jsonp:'callback'和jsonpCallback:'list'就相当于上面url的callback=list