AJAX请求跨域问题的解决方案

当前位置:首页 » Ajax
In 笔记  @2018-04-24

这个问题其实刚入行的时候就碰到了,后来就在接口返回数据返回的函数里加了一行代码:

header("Access-Control-Allow-Origin: *");

一直想总结一下这个让很多新手困扰的跨域问题,现在来说一说。
首先,跨域产生的原因大家可以自行百度。
本地测试从http://localhosthttp://192.168.50.88域请求数据。

测试代码:

前台代码:

$.get('http://192.168.50.88/tp_test/Home/Test/test_jsonp', function(data) {
    console.log(data);
});

后台代码:

public function test_jsonp(){
    $data = json_encode(array(
        'uid'=>5465,
        'nick'=>'刘德华1265'
    ));
    echo $data;
}

在不做任何处理的情况下浏览器会提示跨域权限问题的,无法获取到数据。

Failed to load http://192.168.50.88/tp_test/Home/Test/test_jsonp: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access

解决方案

方案一:JSONP

这个方案虽然很古老,但依然有效,对于小型的GET请求任务还是可以胜任的,原理很取巧,理解它还是很有必要的;
他的原理就是,通过向页面添加<script></script>标签,加载接口,后台接口按照约定好的将数据放到接口中获取到的callback函数中,前台通过这个函数运行来获取到数据。
代码修改如下:
前台代码:

// callback函数叫jsonp_callback
$(document).ready(function() {
    CreateScript('http://192.168.50.88/tp_test/Home/Test/test_jsonp?callback=jsonp_callback');
});
// callback函数jsonp_callback
function jsonp_callback(data){
    console.log(data);
}
// 添加script标签
function CreateScript(src){  
    $("<script><//script>").attr("src", src).appendTo("body");
} 

后台代码:

public function test_jsonp(){
    $callback = $_GET['callback'];
    $data = json_encode(array(
        'uid'=>5465,
        'nick'=>'刘德华1265'
    ));
    echo "{$callback}({$data})";
}

可以看到,已经可以正确的将数据获取到了,这也就是JSONP的实现过程,由于这样的实现原理,导致了JSONP的两个问题:
1. 需要后台配合返回约定格式的数据。
2. JSONP只能发送GET请求。
而在使用Jquery封装好的jsonp请求时,就会更加方便一些了,同样的后端代码,前端代码就可以做简化了:

$.ajax({
    url: 'http://192.168.50.88/tp_test/index.php/Home/Test/test_jsonp',
    dataType: 'jsonp',
    jsonp:'callback',
})
.done(function(data) {
    console.log(data);
})

Jquery的封装帮我们完成了所有前台需要完成的工作,只需要后台将数据放到callback中返回就可以了。
由于JSONP只能发送GET请求,其他的场景就需要第二种方案;

方案二:HTTP访问控制(CORS)

CORS是一个W3C标准,全称是”跨域资源共享”Cross-origin resource sharing。它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
CORSJSONP的使用目的相同,但是比JSONP更强大。JSONP只支持GET请求,CORS支持所有类型的HTTP请求。JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。
CORS的用法很简单:我们只需要的被请求的接口的回复头中添加:

// 星号表示所有的域都可以请求这里的数据
Access-Control-Allow-Origin: *
//或者指定域,例如上面的测试中我们需要加入即可正常得到数据了
Access-Control-Allow-Origin: http://localhost

关于CORS更多的设置和用法请自行搜索。

标签: , , , , ,   评论: 1枚 

Ajax弹窗编辑无刷新查询赋值

当前位置:首页 » Ajax
In 学习  @2016-03-04

题目很拗口,需求是这样的;
在项目中有一个列表页的右侧的编辑按钮是弹窗式的这时候就没有url跳转,无法使用一般的跳转查询取值,需要通过点击触发取值查询并赋值的过程。

封装了一个jQueryAjax函数:

function addhidden(id,url){
    var res = 0;
    var data ={"id":id};
    res = $.ajax({
        type:'POST',
        url:url,
        data:data,
        async :false,
        dataType : "json",
        success: function(data){
        },
    })
    res = res.responseText;
    res = eval("("+res+")");
    return res;
    }

调用上面的addhidden函数查询值并返回数据;

//当点击该标签时触发事件
$(".btn.btn-xs.btn-info.addhidden").click(function(){
        //调用ThinkPHP控制器中的isfind函数执行查询
    var url="{:U('Blog/isfind')}";
    //从模板num标签中为id赋值
        var id= $(this).attr("num");
    var data = addhidden(id,url);
    $("#id").val(data.id);
    $("#form-field-mask-2").val(data.title);
    $("#form-field-mask-3").val(data.sort);
</pre>

Blog控制器类的isfind函数:
<pre lang="php" line="0">
//弹窗修改分类取值
public function isfind(){
    if($_POST['id']){
        $blog=M("blog");
        $res=$blog->where(array('id'=>$_POST['id']))->field("id,title,sort")->find();
        $this->ajaxReturn($res);
    }
}

模板文件:

<tbody>
    <volist id="list" name="list">
    <tr>
        <td>{$list.title}</td>
        <td>{$list.time}</td>
        <td>
            <div class="visible-md visible-lg hidden-sm hidden-xs btn-group">
                <a class="btn btn-xs btn-info addhidden" href="#" name="edit" data-toggle="modal" data-target="#Edit" num="{$list.id}" title="编辑">
                <i class="icon-edit bigger-120"></i>
                </a>
                <a class="btn btn-xs btn-danger" name="trash" title="删除" num="{$list.id}">
                <i class="icon-trash bigger-120"></i>
                </a>
                <a class="btn btn-xs btn-warning" href="{:U('Blog/adds',array('pid'=>$list['id'],'title'=>$list['title']))}" name="add" title="添加" num="{$list.id}">
                <i class="icon-plus bigger-120"></i>
                </a>    
                <a class="btn btn-xs btn-success" href="{:U('Blog/mulcolum',array('pid'=>$list['id'],'title'=>$list['title']))}" name="view" title="所属内容" num="{$list.id}">
                <i class="icon-list bigger-120"></i>查看所属内容
                </a>                                                                
            </div>
        </td>
    </tr>
    </volist>
</tbody>
标签: , ,   评论: Ajax弹窗编辑无刷新查询赋值已关闭评论