【问题标题】:Getting php to properly format jsonp response to populate div让 php 正确格式化 jsonp 响应以填充 div
【发布时间】:2015-07-20 16:09:09
【问题描述】:

我花了几天时间寻找这个问题的答案,我已经接近了,但我似乎无法让它真正起作用。

我希望 example1.com 向 example2.com 提交请求,其中 example2.com 处理该请求,并且 example1.com 在 div 中显示输出而不重新加载页面。

这是我所拥有的:

example1.com (html)

<div class="option">
 <form id="option" action="https://example2.com/process.php" method="get">
   <div class="input">
     <div id="option">
       <div class="block">
         <div class="title">Select Option</div>
         <div class="input-resp"><span>
           <select name="cmd">
               <option name="option" value="online">Online</option>
               <option name="option" value="offline">Offline </option></span>
             </div>
       </div>
     </div>
   </div>
   <div class="submit">
   <input type="submit" value="SUBMIT" />
   </div>
 </form>
</div>
<div class="response">
  <div id=response></div>
</div>

example1.com (javascript)

$('#option').submit(function() { // catch the form's submit event
$.ajax({ // create an AJAX call...
    cache: true, // remove jsonp callback from url
    dataType: "jsonp", // use jsonp for cross domain requests
    jsonp: false, // remove jsonp timestamp from url
    data: $(this).serialize(), // get the form data
    type: $(this).attr('method'), // GET or POST
    url: $(this).attr('action'), // the file to call
    success: function(result) { // on success..
        $('#response').html(result); // update the DIV
    }
});
return false; // cancel original event to prevent form submitting
});

注意:为了测试,我在 ajax 调用中添加了一些设置,试图从 URL 中删除回调和时间戳。当我直接导航到页面时,没有它们就可以正常工作,但是当我尝试使用修改后的 URL(带有回调和时间戳)直接导航时失败。

理想情况下,我宁愿不使用添加的设置来删除回调,但我只是不知道如何使用 php 处理它以获得响应。

这些是 apache 访问日志:

[09/May/2015:14:32:20 -0700] "GET /process.php?cmd=online HTTP/1.1" 200 1110  // Without callback and timestamp

[09/May/2015:14:31:16 -0700] "GET /process.php?callback=jQuery172026217079092748463_1431207074531&cmd=online&_=1431207076762 HTTP/1.1" 200 4765  // With callback and timestamp

这就是我在 php 中处理请求的内容。 (同样,当我直接导航到文件时,这会在浏览器中产生一些预期的输出)。

example2.com/process.php

header('Content-Type: text/javascript; charset=utf8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Max-Age: 3628800');
header('Access-Control-Allow-Methods: GET, POST');

if ($_GET[cmd] == "online") {
$output = shell_exec('some server side commands');
$oparray = preg_split('/[\s,]+/', $output);
$odd = preg_split('/[\s,]+/', $output);
$even = preg_split('/[\s,]+/', $output);
foreach ($oparray as $key => $value) {
  if (0 == $key % 2) {
    $even[] = $value;
    //echo $_GET['callback'] . '('.json_encode($value).')';  //this didn't work
    $json = json_encode($value);
    $jsonp_callback = isset($_GET['callback']) ? $_GET['callback'] : null;
    print $jsonp_callback ? "$jsonp_callback($json)" : $json;
  }
  else {
    $odd[] = $value;
    // echo $_GET['callback'] . '('.json_encode($value).')';  //this didn't work
    $json = json_encode($value);
    $jsonp_callback = isset($_GET['callback']) ? $_GET['callback'] : null;
    print $jsonp_callback ? "$jsonp_callback($json)" : $json;
  }
 }
}

现在我相当有信心,就 jsonp 而言,我没有正确处理这个问题,但我似乎无法得到任何有用的错误。我尝试在错误设置中添加console.log(error);,结果只在firebug的控制台中显示202成功。

error: function(error){
        console.log(error);
    }

我还尝试了alert(error);,并在弹出窗口中给了我object Object

非常感谢任何帮助完成这项工作。

【问题讨论】:

  • Content-Type 标头还需要以输出类型为条件。还将类型 OPTION 添加到允许的方法中。应该有足够的标题,甚至不需要 jsonp。如果未指定 jsonp,浏览器将发送预检请求 (OPTION),并且只有 json 以查看远程域是否启用了 CORS……然后如果 OPTION 返回正确的标头,则发送完整请求
  • 对于使用 jsonp 的 ajax 中的错误...jQuery API 文档会告诉您错误回调不适用于 jsonp。但是您可以在浏览器开发工具 (f12) 的网络选项卡中检查实际的响应正文...以确切了解您得到了什么
  • 好的,所以我尝试不使用 jsonp,所以我可以看到错误是什么。我得到状态文本“错误”。我还尝试简单地回显 $value 以查看是否可以简单地得到响应……什么也没有。我确实注意到我没有收到任何带有任何标记的 ResponseHeaders 或 RequestHeaders。我会检查实际的回复,然后发回我的结果。

标签: javascript php jquery ajax jsonp


【解决方案1】:

这对我有用。

example1.com (HTML)(保持不变)

<div class="option">
<form id="option" action="https://example2.com/process.php" method="get">
  <div class="input">
    <div id="option">
      <div class="block">
        <div class="title">Select Option</div>
        <div class="input-resp"><span>
        <select name="cmd">
           <option name="option" value="online">Online</option>
           <option name="option" value="offline">Offline </option></span>
        </div>
      </div>
    </div>
  </div>
  <div class="submit">
    <input type="submit" value="SUBMIT" />
  </div>
</form>
</div>
  <div class="response">
    <div id=response></div>
  </div>

我添加了 jsonpCallback 设置(这是我缺少的一部分)。响应字符串应类似于peers(["string of data]),其中peers=callback

这是它的样子

example1.com (javascript)

$('#peers').submit(function() { // catch the form's submit event
  $.ajax({ // create an AJAX call...
    cache: true, // remove jsonp callback from url
    dataType: "jsonp", // use jsonp for cross domain requests
    jsonp: "jsonp", // set callback option in url
    jsonpCallback: "peers",  /set callback for response string
    data: $(this).serialize(), // get the form data
    type: $(this).attr('method'), // GET or POST
    url: $(this).attr('action'), // the file to call
    success: function(result) { // on success..
        $('#response').text(result); // update the DIV
    }
  });
return false; // cancel original event to prevent form submitting
});

由于 jsonp 使用回调修改了 url,我在 example2.com/process.php 中添加了一个检查,并使用回调正确格式化字符串。

这就是它的样子。

example2.com/process.php

if (isset($_GET[jsonp]) && $_GET[cmd] == "online") {
  header('Content-Type: text/javascript; charset=utf8');
  header('Access-Control-Allow-Origin: *');
  header('Access-Control-Max-Age: 3628800');
  header('Access-Control-Allow-Methods: GET, POST, OPTION');
  $output = shell_exec('some server side commands');
  $callback = $_GET[jsonp];
  $array = array($output);
  $json = json_encode($array);
  echo $callback.'('.$json.');';
}

像魅力一样工作。

【讨论】:

    猜你喜欢
    • 2014-02-27
    • 1970-01-01
    • 2022-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多