【问题标题】:Not receiving post data in Codeigniter AJAX form未以 Codeigniter AJAX 形式接收帖子数据
【发布时间】:2016-05-02 06:13:04
【问题描述】:

我正在尝试通过 AJAX 请求将简报表单发布到 Codeigniter。 我正在使用 CSRF 保护。 我有以下代码,我似乎无法获取发布的值,因此无法正确返回响应。 发生了几件不同的事情:

  1. 如果我在输入字段中有 name="email",CSRF 失败,我得到 500 (Internal Server Error)
  2. 如果我忽略它,那么我会将以下内容打印到控制台,这意味着它确实会进入控制器但不会获取帖子值。 (undefined 是对 ajax() 函数的响应

    未定义

    Object {status: "error", message: "请填写正确的邮箱地址", email: " Email: "}

  3. 如果我保留 name="email" 并在 ajax() 顶部执行 console.log(data) ,那么我将值作为不同的对象,就像这样

    [对象],[对象]

    对象名称:“csrf_test_name”值:“e31943d629f0a47d449f21997c220446”

    对象名称:“电子邮件”值:“my@email.com”

我正在尝试在不同的函数中使用表单和 AJAX 请求,以便仅在创建新表单时再次编写表单处理程序。

谁能指出我做错了什么?我相信序列化时的格式有些东西我不明白。目前我只登录到控制台,因为我迷失在错误所在的位置。

HTML

<form role="form" id="subscriber_form">
    <input id="csrf" type="hidden" name="<?php echo $this->security->get_csrf_token_name(); ?>" value="<?php echo $this->security->get_csrf_hash(); ?>"/>
    <div class="alert hidden" id="returnmessage">
    </div>
    <div class="form-group form-group-default input-group">
       <label>Email address</label>
       <input type="email" id="email" name="email" class="form-control" placeholder="name@company.com" required />
    </div>
    <button id="subscribe_submit" class="btn btn-success btn-block" type="button">Subscribe!</button>
</form>

Javascript (JQuery 1.11.1)

function ajaxSubmit(form,url,data){
    console.log(data);
   $.ajax({
    type: 'POST',
    url: url,
    dataType: 'JSON',
    data: data,
    success: function (response) {
        console.log(response);

    }
  });
}

$('#subscribe_submit').click(function(e){
    e.preventDefault();

    var form = '#subscriber_form';
    var url = 'subscribers/save_subscriber';
    var data = $(form).serializeArray();

    var response = ajaxSubmit(form, url, data);

    console.log(response)
});

PHP (Codeigniter 3.0)

function save_subscriber(){

    $data = array(
        'email' => $this->input->post('email'),            
        'created' => date('Y-m-d H:i:s')
    );

    $success_response = array(
        'status' => 'success',
        'message'=> 'You now subscribe to our newsletter'
    );
    $error_response = array(
        'status' => 'error',
        'message'=> 'Please fill in a correct email address',
        'email' => " Email: ". $data['email']
    );
     $valid_email = validate_email($data['email']);
     if ($data['email'] != "" && $valid_email == TRUE) {        
        $this->_insert($data);
        $response = $success_response;
    }
    else{
        $response = $error_response;
    }
    echo json_encode($response);

}

此外,我尝试使用 ajaxSetup 和 JQuery cookie 进行设置,但没有成功,因为我无法将数据输入函数。我以为它是全球性的。

$.ajaxSetup({
     data: {
         "csrf_test_name": $.cookie('csrf_cookie_name')
     }
});

编辑 我已经部分解决了这个问题。我打开了日志记录

$config['log_threshold'] = 2;

发现我从 CI 2.0 复制的模型中有错误。这样就解决了获取帖子值的问题。

详细说明 我还意识到我无法按照上面的 AJAX 请求进行解释,因为这会使请求不异步或在等待响应时停止浏览器。

【问题讨论】:

  • url 定义在哪里??表明
  • URL 在表单处理程序中定义 var url = 'subscribers/save_subscriber';如果我从表单中删除name="email",那么我会得到这个响应而不会出现任何服务器错误。 Object {status: "error", message: "Please fill in a correct email address", email: " Email: "} 它只是没有收到控制器中的 post 值。
  • 没有base_url你不能调用站点路径
  • 当它显示服务器错误 500 时,即使在控制台中也能找到正确的控制器。如果我添加完整路径,那么它没有帮助。
  • 您在不修改内容类型标头的情况下回显 JSON。我建议在输出任何内容之前使用$this-&gt;output-&gt;set_content_type('application/json')。我还建议使用 $this-&gt;output-&gt;set_output() 而不是 echo 以避免标题问题。

标签: jquery ajax codeigniter csrf


【解决方案1】:

而不是使用:

var data = $(form).serializeArray();

使用

var data = $(form).serialize();

serialize() 方法生成正确的表单编码,由$_POST$_GET 接收

serializeArray() 创建完全不同的结构,例如:

[
  {
    name: "email",
    value: "1"
  },
  {
    name: "password",
    value: "2"
  }
]

【讨论】:

  • serializeserializeArray 的选择不是答案。该选择不会以任何方式影响结果。实际上,如果您查看 jQuery 源代码,您会发现 serialize() 所做的第一件事就是调用 serializeArray()
  • @DFriend 你有权发表你的意见,但是数组必须循环访问每个name/value,而不是自动将名称作为$_POST 或$_GET 的键。 serialze() 将数据编码为额外的步骤,以与默认浏览器提交过程完全相同的格式发送数据。另请注意,serilalizeArray() 需要递归重组所有在表单控件本身中设置为数组表示法的名称
  • 这里是来自 jquery.js 的 serialize 的完整源代码 serialize: function() { return jQuery.param( this.serializeArray() ); }, 函数 jQuery.param 实际上完成了创建查询字符串的工作。如果您查看ajax 函数的源代码,您会发现如果data 还不是字符串,它会调用jQuery.param。因此,选择serializeserialzeArray 来获得data 没有区别。无论哪种方式,格式正确的数据都将发送到服务器。您的回答与结果无关。
  • @DFriend 如果 OP 不期望数据的结构与默认表单 post 会产生的不同,它肯定会这样做。我知道 $.param 是如何工作的,它基本上简化了在服务器上进行转换的需要。如果数据以serlializeArray() 发送,OP 无法使用$_POST['name'] 访问输入中的name 而不执行转换服务器端
  • 我可能很密集,但定义 OP。
【解决方案2】:

问题已解决。答案与问题没有直接关系。我打开登录 Codeigniter 并在其他地方发现错误,但没有显示。感谢您的帮助。

【讨论】:

    猜你喜欢
    • 2015-03-02
    • 1970-01-01
    • 1970-01-01
    • 2019-07-21
    • 2013-04-03
    • 1970-01-01
    • 1970-01-01
    • 2017-02-19
    • 1970-01-01
    相关资源
    最近更新 更多