Ajax 请求的坑

目录

一、Ajax 请求的 CSRF 保护机制

1.php 的 CSRF 保护机制的代码演示如下(面向过程演示,现在的 php 开发,几乎不会使用面向过程开发,而是面向对象):

效果图:

2.因此,Ajax 向后端发出请求时,Ajax 方法体的数据输入要带上 CSRF 保护标志,否则后端不会响应:

二、jQuery 的 Ajax 不要用下面的写法,原因就是,在 403、404 或者 505 的情况下不会有提示,在调试或者用户体验上都很麻烦。

三、jQuery 的 Ajax 最好使用下面的写法,会有错误提示,在调试或者用户体验上都要好的多。如果遇到 404 的情况,一般认为是 Ajax 的 url 写错了;如果是 505 的情况,一般认为是后端页面可能报错了;如果是 403 的情况,可能是前端的 csrf 与后端的值不匹配。

四、一个函数体包含 Ajax 的函数体时,Ajax 内 return 的数据不会直接返回给函数体,也就是函数体获取不到 Ajax 返回的数据,用下面的方法才能正确获取,Ajax 必须使用同步请求!

index.php 文件:

text.php 文件:

五、自定义一个 Ajax 请求模板:


一、Ajax 请求的 CSRF 保护机制

  开发普通页面,在一般情况下,我们使用 jquery 的 Ajax 代替原生 js 向后端发起请求是很方便的。后端在一般情况下,我们使用的是像 laravel、Yii、ThankPHP 或者 CodeIgniter 等等这样的框架。这些框架无一例外都使用了 CSRF 保护机制,什么是 CSRF?CSRF 跨站点请求伪造(Cross—Site Request Forgery),跟XSS攻击一样,存在巨大的危害性。简单理解一下,最常见的情况,就是 A 站点的页面去请求 B 站点的 RestFul 接口请求,所以 CSRF 保护机制非常重要。因此 Ajax 向后端请求时遇到最大的坑,就是忘了要带上 CSRF 标志,而后端认为这是在跨站点请求。下面是以 jQuery 的 Ajax 为例。

1.php 的 CSRF 保护机制的代码演示如下(面向过程演示,现在的 php 开发,几乎不会使用面向过程开发,而是面向对象):

1)前端页面 index.php:

<?php
/**
 * 前端页面
 */
session_start();

//生成随机字符串
function randomStr($max = 16){
    $str = 'abcdefghijklmnopqrstuvwxyz'.
           '0123456789'.
           'ABCDEFJHIJKLMNOPQRSTUVWXYZ';
       
    $val = '';
    $str = str_shuffle($str);  //打乱字符串
    for($i = 0; $i < $max; $i++){
        $val .= $str[rand(0, strlen($str) - 1)];
    }
    
    return $val;
}
 
$_SESSION['token'] = randomStr();
 
//此函数给URL重写机制添加名/值对。
//此函数要写在 html 页面前端中;如果是 MVC 模式,应包含在 view 视图文件内
output_add_rewrite_var('token', $_SESSION['token']);
include_once 'view.php';
print_r(ob_list_handlers()); 

2)后端页面 form.php:

<?php
/**
 * 后端页面
 */
session_start();

echo '原始的值:'.$_SESSION['token'].'<br>收到的值:'.$_POST['token'].'<br>';

// 服务端判断 token 后执行。
// 处于安全考虑,判断是否相等时应该使用 === 来判断,即类型相等,内容相等。
if(filter_has_var(INPUT_POST, "token") && $_POST['token'] === $_SESSION['token']){

    // 这是防 CSRF 后接收到的数据
    echo '<strong style="color:red">安全地收到数据了!内容为:'.$_POST['var2'].'</strong><br>';
}

print_r(ob_list_handlers()); 

3)view 视图页面 view.php:

<div>
    <a href="file.php">link</a>
    <a href="http://example.com">link2</a>
    <form action="form.php" method="post">
        <input type="text" name="var2" value="这是默认值!"/>
        <input type="submit" value="确定">
    </form>
</div>

效果图:

2.因此,Ajax 向后端发出请求时,Ajax 方法体的数据输入要带上 CSRF 保护标志,否则后端不会响应:

$.ajax({
    data: {
        "<?= csrf_token() ?>": csrf  // csrf 保护(CodeIgniter 框架演示)
    },
    url:"https://url.com/class/function",
    success:function(data){
        // 成功后的方法体
        return true;
    },
    error:function(x){
        // 失败后的方法体,一般像下面这样给出提示即可,一般 403、404 都会成功给出提示。
        // swal 是 sweetalert 模态框框架的提示框,相当于 js 的 alert()
        swal("提示:", "错误提示:" + x.status + " " + x.statusText + ",请刷新页面重试!", "error");
        return false;
    }
});

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰雪青松

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值