0

I am trying to pass data via Ajax to userData.php but cannot figure out why I am getting the following error 'an error occurred trying to load resource'.

Here is the js code:

myApp.onPageInit('form-elements', function(page) {

    $$('.page[data-page=form-elements] form[name=form]').on('submit', function(e) {
    e.preventDefault();
    var formData = myApp.formToData(e.target);
        $.ajax({
            type: "POST",
            dataType: 'json',
            url: "//autoapp.webxdetroit.com/material/assets/custom/php/userData.php",
            // url: "assets/custom/php/userData.php",
            data: {userData : formData },
            headers: {
                "cache-control": "no-cache"
            },
            success: function( data ) {
                window.location.href='assets/custom/php/camera.php'
        },
            error: function(jqXHR, exception) {
            if (jqXHR.status === 0) {
                alert('Not connect.\n Verify Network.');
            } else if (jqXHR.status == 404) {
                alert('Requested page not found. [404]');
            } else if (jqXHR.status == 500) {
                alert('Internal Server Error [500].');
            } else if (exception === 'parsererror') {
                alert('Requested JSON parse failed.');
            } else if (exception === 'timeout') {
                alert('Time out error.');
            } else if (exception === 'abort') {
                alert('Ajax request aborted.');
            } else {
                alert('Uncaught Error.\n' + jqXHR.responseText);
            }
        }

});

    });

});

Here is the php:

  <?php

session_start();

require_once "pdo.php";
require_once "util.php";

unset($_SESSION['user_id']); //To log the last user out
unset($_SESSION['employee_id']); //To log the last user out

//  Handle the incoming data
if ( isset($_POST['userData'])) {
   $msg = validateProfile();
   if( is_string($msg)){
     $_SESSION['error'] = $msg;
     header("Location: userData.php");
     return;
   }

// Set user data variable
$userData = $_POST['userData'];

$stmt = $pdo->prepare('INSERT INTO User (name, email, phone, vin, mileage, employeeid)
   VALUES(:nm, :em, :ph, :vin, :mi, :eid)');

 $stmt -> execute(array(
   ':nm' => $userData['input_name'],
   ':em' => $userData['input_email'],
   ':ph' => $userData['input_phone'],
   ':vin' => $userData['vin'],
   ':mi' => $userData['mileage'],
   ':eid' => '1')
 );

 $row = $pdo->lastInsertId();
 echo($row);


 // Set session user_id
 $_SESSION['user_id'] = $row;


 // redirect the browser to index.php
 $_SESSION['success'] = "User Added";
 header("Location: userData.php");
}

?>


<!DOCTYPE html>
<html lang=“en”>
 <head>
   <meta charset=“UTF-8”>
   <title>Alex Lennard's Profile Add</title>
 </head>

 <body>
 <!-- Print flash message -->
   <?php
   flashMessages();
   ?>
 </body>
</html>

And here is the util.php:

<?php

function flashMessages(){
  if ( isset($_SESSION['error'])){
    echo('<p style="color:red;">'.htmlentities($_SESSION['error'])."</p>\n");
    unset($_SESSION['error']);
  }
  if ( isset($_SESSION['success'])){
    echo('<p style="color:green;">'.htmlentities($_SESSION['success'])."</p>\n");
    unset($_SESSION['success']);
  }
}


function validateProfile(){

  $userData = $_POST['userData'];

  if ( strlen($userData['input_name']) == 0 || strlen($userData['input_email']) == 0  ||
    strlen($userData['input_phone']) == 0  || strlen($userData['vin']) == 0  ||
    strlen($userData['mileage']) == 0 ){
    return "All fields are required";
  }
  if ( strpos($userData['input_email'], '@') === false){
    return "Email address must contain @";
  }
  return true;
}

?>

This code works OK on google chrome (desktop), but does not work in safari (desktop/mobile) or chrome (mobile).

If i submit a blank form in Safari then I will get a blank submission in my database but will still get the above error. As soon as I try to populate the fields nothing will go through.

Screenshot 1

Screenshot 2

Alex
  • 47
  • 1
  • 6
  • Welcome to SO. I just tested out your website and it doesn't seem like your server is sending any proper response, but I'm not quite sure. Directly visiting your [PHP script](https://autoapp.webxdetroit.com/material/assets/custom/php/userData.php) throws a 500 error. Could be that everything but Chrome desktop is sensitive to that, but it's an issue in your PHP either way. Slick app btw. – sheng Oct 23 '18 at 19:16
  • 1
    Your code is not complete OR has some blatant syntax errors. Please post the surrounding code that is missing above. – Randy Casburn Oct 23 '18 at 19:16
  • Thanks @ShengSlogar! This is the first app that I'm building, also the first time on SO. I'll take a look into the 500 error, is there anything else I can post that would give you some more insight? – Alex Oct 23 '18 at 19:37
  • @RandyCasburn Is there a specific part that you are looking for? I just updated the post to the full php code. The js is coming from a framework7 app and I didnt think it was necessary to post all 1300 lines – Alex Oct 23 '18 at 19:39
  • @Alex Woo! You're doing good so far. Try and narrow it down to a specific chunk or line in your PHP and then comment back with your result. Some good debugging tools are [Postman](https://www.getpostman.com/) for testing your XHR request and the PHP [die](http://php.net/manual/en/function.die.php) function. You can use the latter progressively through your code until you hit an error spot. If you really *really* can't make any progress, comment back with that as well. Chances are you're gonna smack yourself a few minutes in. – sheng Oct 23 '18 at 20:03
  • 1
    We don't have a clue what `myApp.formToData(e.target);` produces and although you have a comment in your PHP code, you never validate that data on the server side. You might think about ensuring that data has what you expect and is in the correct structure. – Randy Casburn Oct 23 '18 at 23:49
  • @ShengSlogar The first thing that I found was that 'name' was being set to 'null' which was causing a database error. I added the validation to the $_POST but have fallen into the same trap as before (working on chrome desktop but not anything else). I checked the error_log and am not longer getting a php error, although after pressing submit I am still receiving 'an error occurred trying to load resource'. The userData.php gives a 200 OK on its own. I'm trying to think of another way to troubleshoot, if you have any ideas please let me know. Code is also updated above – Alex Oct 24 '18 at 02:19
  • @Alex I tested your code in Safari (Firefox works for me) and I'm getting an `Access-Control-Allow-Origin` request. Probably has to do with you hosting your app on HTTP and querying your API with HTTPS, triggering a preflight OPTIONS request that you're not properly handling (see [this article](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Preflighted_requests)). Generally want to stick with a single HTTP protocol, but if you need to vary for some reason, look into enabling CORS for [Apache](https://enable-cors.org/server_apache.html) or [PHP](https://enable-cors.org/server_php.html). – sheng Oct 24 '18 at 11:55
  • @Alex I should clarify the OPTIONS request is not guaranteed with cross-origin (which includes http/s) requests, but it's triggered because you added a `cache-control` header -- it's a combination of both. A bit technical but the MDN article I linked above explains all of that. – sheng Oct 24 '18 at 12:07
  • @Alex ...TLDR as I'm researching, Safari seems to be the one handling this correctly, given the default [same-origin-policy](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy#Definition_of_an_origin). Going between HTTP and HTTPS without explicitly defined `Access-Control-Allow-Origin` headers over the same domain should be prohibited. – sheng Oct 24 '18 at 12:13
  • @Alex Finally, if you go to [https://autoapp.webxdetroit.com/material/](https://autoapp.webxdetroit.com/material/) (note the HTTPS) in Safari and make the same request, it should go through. I just did it myself, yw for all the fake DB entries. If this solves everything for you, I'll write up a detailed answer for future generations. – sheng Oct 24 '18 at 12:17
  • You can also use [`//autoapp...` on your request](https://stackoverflow.com/a/41204493/2535504) or just a same-domain absolute URL `/material/assets...` to avoid anything like this in the future. – sheng Oct 24 '18 at 12:21
  • @ShengSlogar First, you rock, thank you for the help. I changed the path to '//autoapp...' AND added error handling to the ajax call. I did not receive any of the fake DB entries unfortunately, but with the two changes above it is now 'working' on chrome and safari. I am still receiving the original error on userData.php as well as an ajax alert 'Not connect. Verify Network.' And on a side note, if i change the ajax alert to console.log everything stops working again. Currently going through the documentation you sent over, will report back what I find – Alex Oct 24 '18 at 15:24
  • @Alex Still looking into this. Everything seems to go through for me on Safari and Firefox (you can verify w/ DB entries) but Chrome is handling it differently. Not sure what the issue could be. – sheng Oct 24 '18 at 15:53
  • @Alex I would debug validateProfile: `print_r($userData); die;`. I have a feeling some fields aren't getting sent over correctly – sheng Oct 24 '18 at 15:57
  • @ShengSlogar Your test entries are coming through. I am still getting the same error even when I bypass validateProfile(). Have a feeling that it has something to do with jumping to camera.php without waiting for a response? [ajax status code = 0](https://stackoverflow.com/questions/2000609/jquery-ajax-status-code-0) – Alex Oct 24 '18 at 17:31
  • @ShengSlogar Okay, so when I comment out 'window.location.href' I get a 200 OK response from userData.php and 'Requested JSON parse failed.' Getting closer. – Alex Oct 24 '18 at 17:36
  • @Alex Nope, you shouldn't be bypassing `validateProfile`, you should be checking to see what data is coming in first. Oh. Put the `window.location` inside `.done(function(){ // });` at the end of your AJAX request. The JSON parse fail is probably just the result of your PHP quitting and not outputting anything – sheng Oct 24 '18 at 17:37
  • 1
    @ShengSlogar Problem is solved. I was defining th [wrong data type](https://stackoverflow.com/questions/6186770/ajax-request-returns-200-ok-but-an-error-event-is-fired-instead-of-success). Now getting a 200 OK and everything is being sent to the db. Thank you again for your help!! Updated code is posted – Alex Oct 24 '18 at 18:52
  • @Alex Ahh! I was eyeballing those and just went with it. Glad you got that figured out :) – sheng Oct 25 '18 at 01:46

0 Answers0