前端jsonp解决跨域问题

跨域问题的引入

在本地8000端口开启django程序,通过ajax往开启9000端口的django程序发送请求

8000端口的html文件

<input type="button" value="发送1" onclick="submitJsonp1();" />
<script src="/static/js/jquery-3.1.1.js"></script>
<script>
        function submitJsonp1() {
            $.ajax({
                url: 'http://127.0.0.1:9000/ajax1.html',
                type: 'GET',
                data: {nid:2},
                success:function (arg) {
                    $('#content').html(arg);
                }
            })
        }
</script>

9000端口的接口

def ajax1(request):
    ret = {'status':True, 'message': '....'}
    import json
    return HttpResponse(json.dumps(ret))


通过上图我们可以看到请求确确实实是发过去了,也拿到了结果。但是因为浏览器的同源策略结果没有拿到8000站点的范围里。
解决方式是利用src属性的跨域属性,程序员手动创建script标签,利用src属性去发请求,拿到请求结果后删除创建的这个script标签。

自定义script标签解决跨域

html

function submitJsonp2() {
            var tag = document.createElement('script');
            tag.src = 'http://127.0.0.1:9000/xiaokai.html';
            document.head.appendChild(tag);
            document.head.removeChild(tag);
        }

views.py

def xiaokai(request):
    return HttpResponse('ok')

我们发现返回的字符串已经到底script里面,此时script把ok当做一个变量,但是这个变量没有定义,所以报错。解决方式也很简单
后端返回的字符串ok用一个前端函数名包裹

def xiaokai(request):
    return HttpResponse('func("ok")')

前端多定义一个函数

function fuck(arg) {
            console.log(arg)
            $('#content').html(arg);
        }

此时console.log(arg) 就能正常显示字符串'ok' 了

利用ajax的jsonp

html

function submitJsonp4() {
            $.ajax({
                url: 'http://127.0.0.1:9000/xiaokai.html',
                type: 'POST',
                dataType: 'jsonp',
                jsonp: 'callback',
                jsonpCallback: 'func',
                success: function (arg) {
                    console.log(arg)
                }
            })
        }

真实发送的请求为http://127.0.0.1:9000/xiaokai.html?callback=func&_=1529415061035
定义success的好处是类似于匿名函数的概念,如果不设置success,那么就需要额外设置 jsonpCallback 指定的函数名,用了success就相当于万金油了

后端

def xiaokai(request):
    func = request.GET.get('callback')
    return HttpResponse('%s("xxoo")'%func)

jsonp的缺点

jsonp只能发get请求,要想支持所有的请求方式,需要用到cors

原文地址:https://www.cnblogs.com/longyunfeigu/p/9200947.html