简体   繁体   English

第二次调用 jquery 时出现 403 AJAX 错误

[英]Getting 403 AJAX error on second call jquery

I have a simple form with a select field of clients.我有一个简单的表单,其中包含 select 个客户字段。 Once you select a client, i am making an ajax call to fetch the clients logo and display below the select field for the user to see.一旦您 select 成为客户,我就会拨打 ajax 来获取客户徽标并显示在 select 字段下方供用户查看。 This works fine.这很好用。 The AJAX request looks like this: AJAX 请求如下所示:

$.ajax({
  url: '/clients/access_controls/<?php echo basename(__FILE__);?>',
  type: 'post',
  data: clientId,
  //dataType: 'application/json',
  //contentType: 'application/x-www-form-urlencoded',

  error: function(jqXhr, textStatus, errorMessage) {
    alert('ERROR MESSAGE: ' + errorMessage);
    return false;
  },

  success: function(d) {
    $(d.html).insertAfter(tab.find('table tr:eq(0)'));
    var func = d.responseScript;
    if ($.isFunction(eval(func))) {
      eval(func + '()');
    }
  }
});

The problem is, once i select another client from the list, the Ajax call returns an error of 403 FORBIDDEN.问题是,一旦我 select 列表中的另一个客户端,Ajax 调用将返回错误 403 FORBIDDEN。 What could be the issue?可能是什么问题? What baffles me is the first call goes fine, so why does it fail the second time.令我困惑的是第一次调用正常,为什么第二次失败了。 Its a very simple issue, but i have not been able to fix it.这是一个非常简单的问题,但我无法修复它。 I have tried setting different content types with the request, and also tried setting "Access-Control" headers on the PHP file processing the request like so:我已经尝试使用请求设置不同的内容类型,还尝试在处理请求的 PHP 文件上设置“访问控制”标头,如下所示:

header('Content-type: application/json');
//header('Access-Control-Allow-Headers', 'api-key,content-type');

header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Headers: X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method");
//header('content-type: application/x-www-form-urlencoded; charset=UTF-8');

to no avail.无济于事。 Any help will be appreciated.任何帮助将不胜感激。 Thanks in advance.提前致谢。

Here's the php CODE这是 php 代码

if (isset($_POST['request'])) {
  if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
    header('Content-type: application/json');
    //header('Access-Control-Allow-Headers', 'api-key,content-type');

    //header('Access-Control-Allow-Origin: *');
    //header("Access-Control-Allow-Headers: X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method");
    //header('content-type: application/x-www-form-urlencoded; charset=UTF-8');

}

switch ($_POST['request']) {
    case 'logos':
        if (!isset($_POST['sub'], $_POST['value'])) {
            echo json_encode([
                'error' => 'Invalid arguments'
            ]);
            exit;
        }

        $logo = getClientLogo($_POST['value']);
        $html = '<tr><td valign="top">Current Logo:</td><td valign="top" class="client_logo">' . ((!empty($logo)) ? $logo : '<strong>No Logo</strong>') . '</td></tr><tr><td>Upload new logo:</td><td><form method="post" enctype="multipart/form-data" target="member_image" action="/clients/access_controls/' . basename(__FILE__) . '"><input type="file" name="member_image" class="hidden" /><input type="button" value="Select File" data-usage="member_image" data-event="click" data-label="member_filename" />&nbsp;&nbsp;<span class="member_filename">No file selected</span>&nbsp;&nbsp;<input type="submit" value="Upload &amp; Save &gt;" /><input type="hidden" name="request" value="image_upload" /><input type="hidden" name="value" value="' . $_POST['value'] . '" /><input type="hidden" name="iil_token" value="' . getCSRFToken() . '" /></form><input name="member_image" style="display: none;" /></td></tr>';
        print json_encode([
            'html' => $html,
            'responseScript' => 'IIL.applyImageUploadRequirements'
        ]);
        exit;

If you have Mod Security - try turning it off & see if that works.如果您有 Mod Security - 尝试将其关闭并查看是否有效。 I recently had trouble getting 403 errors from an ajax call to a php script - it would give a 403 if the content contained the word 'include'.我最近在从 ajax 调用 php 脚本时遇到了 403 错误 - 如果内容包含单词“include”,它会给出 403。 Turning off mod-security got it working until we found the rule that was at fault.关闭 mod-security 使其正常工作,直到我们发现有问题的规则。

For anyone who might find this beneficial, @Dylan Hamilton-Foster i would say you were close-as in, it was a security check issue.对于任何可能发现这有益的人,@Dylan Hamilton-Foster 我会说你很接近 - 因为,这是一个安全检查问题。 However, my specific situation was unique.但是,我的具体情况很独特。 Here's the thing;事情是这样的; in our in-house framework, we fire a csrf code generated from the same page with every form submitted, and check for it in the processing script.在我们的内部框架中,我们在提交每个表单时触发从同一页面生成的 csrf 代码,并在处理脚本中检查它。 When one first visits the page, the csrf code is sent and so it matches and the request is allowed through.当一个人第一次访问该页面时,会发送 csrf 代码,因此它会匹配并允许请求通过。 But because the second form submission happens without the page refreshing, no csrf is sent through and so the csrf verification script on the processing side rejects the request.但是因为第二次提交表单时没有刷新页面,所以没有发送csrf,所以处理端的csrf验证脚本拒绝了请求。

My solution was basically to set a counter variable and post it with every request (alongside the csrf token) and then increment it on subsequent requests.我的解决方案基本上是设置一个计数器变量并将其与每个请求一起发布(与 csrf 令牌一起),然后在后续请求中递增它。 In the processing script, i modified the token verification to accept the counter variable if it is present.在处理脚本中,我修改了令牌验证以接受计数器变量(如果存在)。

I know this is unsafe and defeats the purpose of using a CSRF token, but我知道这是不安全的并且违背了使用 CSRF 令牌的目的,但是

a) this app was only used internally, and was within our corporate firewall a) 这个应用程序只在内部使用,并且在我们公司的防火墙之内

b) this was a legacy application with the same script being used by multiple other in-house applications, so i wanted to make the least change possible. b) 这是一个遗留应用程序,多个其他内部应用程序使用相同的脚本,所以我想尽可能减少更改。

There you go. It worked well.你是 go。它运作良好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM