为什么 Javascript 和 AJAX 调用(在页面加载时)会导致数据库行为空?(脸书画布)


Why is a Javascript and AJAX call (on page load) resulting in an empty database row? (Facebook Canvas)

我真的希望这里有人能够帮助我解决这个问题!

我正在制作一个Facebook Canvas游戏,但我很难将玩家的详细信息(Facebook ID,名字,姓氏,电子邮件等(输入我的数据库。

这是我试图实现的过程:

当玩家到达游戏主页时,我希望游戏根据数据库检查用户的Facebook ID,以查看玩家的ID和其他详细信息是否存在,这将告诉我他们以前是否玩过该游戏。如果他们的 id/详细信息不包含在数据库中,那么我希望插入它们,并且我希望出现一个 Javascript 消息框,其中包含有关游戏的简短教程。如果检查显示玩家的详细信息已在数据库中,则我希望不显示任何消息框,并且页面应保持不变。

我试图通过在 html 中使用"onload"调用 Javascript 函数来让它工作。Javascript函数包含从Facebook获取用户详细信息的代码,并包含一些AJAX,该AJAX调用PHP脚本将详细信息插入数据库。如果我在标签中使用"onclick"或"onmouseover",这将完美地工作(当我尝试这两种方法时,用户的详细信息被正确输入并出现消息框(。但是,当我尝试使用"onload"方法时,虽然它确实在数据库中创建了一行,但每个单元格都是空的,看起来它正在正确执行代码,但 AJAX 调用没有时间从 Facebook 获取用户的详细信息,因此创建该行时没有值。

这是正常工作的Javascript/AJAX功能,以及它调用的PHP:

function getUserDetails() {

  FB.api('/me', function(response) {
      var userid = response.id;
      var userfirst_name = response.first_name;
      var userlast_name = response.last_name;
      var useremail = response.email;
      var userbirthday = response.birthday;
      var usergender = response.gender;

    $.ajax({
     url: 'insertuserdetails.php',
    data: {'userid' : userid, 'userfirst_name' : userfirst_name, 'userlast_name' : userlast_name, 'useremail' : useremail, 'userbirthday' : userbirthday, 'usergender' : usergender},
    type: "POST",
}).done(function( msg ) {
  alert("php file called, A TUTORIAL COULD GO HERE"+msg);
});
});

}

PHP:

<?php 
session_start();
require_once '/facebook-php-sdk-v4-4.0-dev/autoload.php';
use Facebook'HttpClients'FacebookHttpable;
use Facebook'HttpClients'FacebookCurl;
use Facebook'HttpClients'FacebookCurlHttpClient;
use Facebook'Entities'AccessToken;
use Facebook'Entities'SignedRequest;
use Facebook'FacebookSession;
use Facebook'FacebookSignedRequestFromInputHelper;
use Facebook'FacebookCanvasLoginHelper;
use Facebook'FacebookRedirectLoginHelper;
use Facebook'FacebookRequest;
use Facebook'FacebookResponse;
use Facebook'FacebookSDKException;
use Facebook'FacebookRequestException;
use Facebook'FacebookOtherException;
use Facebook'FacebookAuthorizationException;
use Facebook'GraphObject;
use Facebook'GraphUser;
use Facebook'GraphSessionInfo;
FacebookSession::setDefaultApplication('MYAPPID', 'MYAPPSECRET');
$servername = "XXX";
$username = "XXX";
$password = "XXX";
$dbname = "XXX";

// Create connection
$conn = mysqli_connect($servername, $username, $password, $dbname);
// Check connection
if (!$conn) {
    die("Connection failed: " . mysqli_connect_error());
}
$userid = $_POST['userid'];
$userfirst_name = $_POST['userfirst_name'];
$userlast_name = $_POST['userlast_name'];
$useremail = $_POST['useremail'];
$userbirthday = $_POST['userbirthday'];
$usergender = $_POST['usergender'];
$sql="INSERT INTO player (facebook_id, first_name, last_name, email, birthday, gender) VALUES 
('$userid', '$userfirst_name', '$userlast_name', '$useremail', '$userbirthday', '$usergender')";

if (mysqli_query($conn, $sql)) {
    echo "New record created successfully";
} else {
    echo "Error: " . $sql . "<br>" . mysqli_error($conn);
}
mysqli_close($conn);
?> 

我可以只使用"onclick"和"onmouseover",但这意味着每次用户执行这些操作时,都会对数据库进行多次调用,这真的很混乱,可能会减慢游戏速度。理想情况下,我希望每个会话只调用一次 Javascript 函数(当页面加载时(。

html 中的"onload"导致创建空行:

<body onload="getUserDetails()">

我不确定为什么"onload"返回空值而其他两种方法没有。我想知道将功能延迟几秒钟是否可以解决问题?但我真的不确定,所以我想我会在这里寻求帮助。:)提前感谢!

用于初始化 Facebook Javascript API 的代码:

$( document ).ready(function() {
FB.init({
  appId: MYAPPID,
frictionlessRequests: true,
status: true,
version: 'v2.1'
});
FB.Event.subscribe('auth.authResponseChange', onAuthResponseChange);
FB.Event.subscribe('auth.statusChange', onStatusChange);

更新:我已将@floor的答案标记为有效,因为它解决了我的问题。我现在只有一个问题,但它不直接涉及 AJAX 问题。

我想我可以做一些简单的事情,比如检查 AJAX+PHP 插入是否成功,如果是这样,那么会出现一个教程弹出窗口,如果没有,那么这意味着用户的 id 已经在数据库中,所以不会出现教程。

我的问题是这个检查总是以成功的方式返回(因为无论SQL插入是否成功完成,AJAX调用总是成功的(,所以我问了错误的问题,相反,我需要在我的SQL/PHP脚本的末尾添加一个回显,其值取决于插入语句的成功或失败。然后,我需要在 AJAX 调用中添加一个成功检查,该检查将启动或不启动弹出窗口,具体取决于它从 PHP 脚本接收的回声。

我用来执行此操作的代码是:阿贾克斯:

   $.ajax({
     url: 'insertuserdetails.php',
     data: {'userid' : userid,
           'userfirst_name' : userfirst_name,
           'userlast_name' : userlast_name,
           'useremail' : useremail,
           'userbirthday' : userbirthday,
           'usergender' : usergender},
    type: "POST",
    success: function(response){
                if(response==1){
                        alert( "Success!");
                        }else{
                        alert( "Failed!" );
                             }
                }
   });

而PHP发送成功/失败回显

//If the SQL insert statement completed correctly...
if($sql){
$verify=1;
}else{
$verify=0;
}
echo $verify;

我此代码中一定有错误,因为弹出窗口始终显示"失败!",它在插入成功时(当我使用空数据库运行脚本时(和不成功时(当数据库不为空时/当行在运行脚本之前已经存在(时都会执行此操作。

PHP 应该回显"1",所以 AJAX 应该输出"成功!",但事实并非如此。任何人都可以在我尝试执行的检查中看到错误吗?

给出评论,我认为这段代码会起作用。

 FB.login(function(response) {
  if (response.authResponse) {
    console.log('Welcome!  Fetching your information.... ');
     FB.api('/me', function(response) {
     if (response.error) {
       console.log('Error - ' + response.error.message);
     }
     else {
       var userid = response.id;
       var userfirst_name = response.first_name;
       var userlast_name = response.last_name;
       var useremail = response.email;
       var userbirthday = response.birthday;
       var usergender = response.gender;
       $.ajax({
         url: 'insertuserdetails.php',
         data: {'userid' : userid,
               'userfirst_name' : userfirst_name,
               'userlast_name' : userlast_name,
               'useremail' : useremail,
               'userbirthday' : userbirthday,
               'usergender' : usergender},
        type: "POST",
       }).done(function( msg ) {
         alert("php file called, A TUTORIAL COULD GO HERE"+msg);
       });
     }
    });
  } else {
    console.log('User cancelled login or did not fully authorize.');
  }
 }, {scope: 'email user_birthday'});

因此,这样做是在用户进行身份验证(登录/授予权限(之后,然后 api 请求信息并调用您的 ajax 请求。我认为通过这样做,数据将是可用的。另外,现在您不需要调用此函数,它只需在用户身份验证时发生。

所以现在进入你问题的最后一部分。

您想知道插入是否发生或失败,您可以通过将 sql 查询设置为变量来执行此操作:

$result = mysqli_query($conn, $sql);
if (!$result) {
   $verify=0;
}
else{
  $verify=1;
}
echo $verify;

尝试将调用放入文档就绪函数中。

$(document).ready(function() {
    getUserDetails();
});

这将在主体完全加载后(或者更准确地说,当 DOM 准备就绪时(触发。

http://learn.jquery.com/using-jquery-core/document-ready/