3

I am currently trying to make an AJAX request for a type of form post, but the PHP parse script I am trying to send the data to is returning a 404 error that I can see through Chrome developer tools. Here is my code:

<script type="text/javascript">

function ajax_post(){
    var hr = new XMLHttpRequest();
    var url = "/products/parse.blade.php";
    var productName = document.getElementById("productName").value;
    var quantityInStock = document.getElementById("quantityInStock").value;
    var pricePerItem = document.getElementById("pricePerItem").value;
    var totalValueNumber = quantityInStock * pricePerItem;
    var route = "productName="+productName;
    hr.open("POST", url, true);
    hr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    hr.onreadystatechange = function() {
        if(hr.readyState == 4 && hr.status == 200) {
            var return_data = hr.responseText;
            document.getElementById("status").innerHTML = return_data;
        }
    }
    hr.send(route);
    document.getElementById("status").innerHTML = "processing...";
}

</script>

<div class="container-fluid form-container">
  <div class="row">
    <div class="col-lg-3 col-md-12">

            <div class="form-group">
                <input type="text" name="productName" id="productName" placeholder="Product Name" class="form-control" required>    
            </div>

            <div class="form-group">
                <input type="number" name="quantityInStock" id="quantityInStock" placeholder="Quantity in Stock" class="form-control" required> 
            </div>

            <div class="form-group">
                <input type="number" step="0.01" name="pricePerItem" id="pricePerItem" placeholder="Price per Item" class="form-control" required>  
            </div>

            <input type="submit" value="Create Product Listing" class="btn btn-primary" onclick="ajax_post();">

            <hr>
            <div id="status"></div>

    </div>
  </div>
</div>

I am using Laravel, and both this view products.create and the file I am trying to use to parse the data, products.parse are both in the products directory of my views folder. But, when I try to submit, all I get is a response of "processing" in the status div, and a 404 error for the route mydevsite.dev/products/parse in Chrome's dev console.

My thought it that I needed to define a route, so I added:

Route::post('/products/parse', 'ProductController@parse'); 

Which returns

return view('products.parse');

But this just changes my error to a 419. I'm thinking it has something to do with CSRF field, but I'm not sure how to include that because it my html is not a form, but simply has form elements. Why is my route returning a 404 or 419 error, and how do I fix this?

develpr
  • 1,296
  • 4
  • 22
  • 42

2 Answers2

2

You're posting to wrong URL.

It must be like this :

var url="/products/parse";

and you need to send CSRF token as well(else it would cause 419 error), which is described here :

put this meta tag inside your <head> tag:

<meta name="csrf-token" content="{{ csrf_token() }}">

Then access it by jQuery like this:

$('meta[name="csrf-token"]').attr('content')
1

You are hitting the wrong route. This variable

var url = "/products/parse.blade.php"; 

should be this

var url = "/products/parse";

You want to call the route that is defined here

Route::post('/products/parse', 'ProductController@parse'); 

You are trying to call the blade file that the route is returning which isn't the correct way to do it. Plus that file isn't located in your public directory.


You could try using fetch instead. It would look something like this:

document.getElementById("status").innerHTML = 'processing...'
let form = new FormData()

form.set('one', '1')
form.set('two', '2')

fetch(url, {
  method: 'POST',
  // Credentials may or may not be required. 
  // It depends if cookies are needed or not.
  credentials: 'include',
  body: form,
  headers: {
    'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
  }
}).then(response => response.text())
  .then(text => {
    document.getElementById("status").innerHTML = text
  })
Get Off My Lawn
  • 34,175
  • 38
  • 176
  • 338
  • @hoolakoola have you tried using [fetch](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch) inestead? – Get Off My Lawn Jul 03 '18 at 15:16
  • @GetOffMyLawn using raw XHR won't cause 419 error :) the CRRF token thing, as I said, is the problem – Hamidreza Kalantari Jul 03 '18 at 15:34
  • @HamidrezaKalantari looks like you are right https://stackoverflow.com/questions/46472812/ajax-laravel-419-post-error – Get Off My Lawn Jul 03 '18 at 15:37
  • @HamidrezaKalantari yes that was the issue, I added `hr.setRequestHeader("X-CSRF-TOKEN", $('meta[name="csrf-token"]').attr('content'));` and it solved it. Thank you both. – develpr Jul 03 '18 at 15:38