Ajax post request correct, but failing on IIS - php

Built a site out on an apache server and it has now been moved to its final home on an IIS server running php 7.2. I use jQuery based ajax post requests on the site for sending form data to the back end and updating the page. This worked great on the apache server, but once I get the code and database up on the new IIS server, this stopped working. The network tab in the developer console shows the file is being hit, and I get a status 200 back. The header shows the form fields correctly, but there is nothing in the response from the file (should just be an echo of the post array.
Here is the ajax request:
$.ajax({
type: 'get',
url: '/ajax/users.php',
data: 'createUser=1&' + $("form[name=addUser]").serialize(),
success: function(msg) {
console.log(msg);
}
});
And here is the /ajax/users.php file:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
echo "<pre>"; print_r($_REQUEST); echo "</pre>";
?>
Headers:
Request Method: POST
Status Code: 200 OK
RESPONSE:
Content-Length: 169
Content-Type: text/html; charset=UTF-8
Date: Thu, 27 Sep 2018 05:59:20 GMT
Server: Microsoft-IIS/8.5
X-Powered-By: PHP/7.2.7
REQUEST:
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Content-Length: 95
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Host: somehost
Origin: http://somehost
Referer: http://somehost/users
If I directly navigate to the file and put the form data in the URL, the page works as expected, it only has this issue when it is via an ajax request (get or post), and only on this IIS server. On the old Apache, the code works as expected.
Any ideas of a setting I might be missing? Or why AJAX would not work properly? I don't control the server personally, but have access to that person via email.

Related

CORS, OPTIONS and PreFlight problems Consuming REST API with Axios in Vue.js

I'm developing a front end to a PHP based application that runs a custom management tool. My goal is to use Vue.js to build out the front end and specifically use Axios to make the API calls.
I'm using a Lightsail server with a public port forward.
Visual Studio Code with Remote Developer tools installed and connected via SSH to develop on that server rather than my machine.
Vue CLI 3 to set up my project and choosing the default packages of Babel and Linting.
Axios is installed via npm.
Our PHP environment originally allowed me to pass params like user ID, API Key and a query ( while user = x method=get, apikey=x, ) and I could easily consume the data and output it in a v-for and everything worked pretty well. But, it was not a well designed API structure, so we changed the idea that params would be passed, as I did not like passing the API key in the URL and don't like the idea of having to pass a SQL query to get the data. So, my colleague adjusted the API so now we have a URL that is like https://tunnel.host.com/api/sites/read.php. We'll also have PHP files for the rest of the CRUD operations later. But I need to get past my current problem.
My research immediately led me to the issue of CORS and I've spent many hours reading about that topic and ultimately feel like it is the issue preventing me from passing the necessary headers to the server and getting access.
I thought for a while that installing the CORS npm package would help, but that appears to only be for fixing the issue with a locally hosted server environment. ( like using ExpressJS as the server in a dev environment )
After reading the Mozilla docs regarding CORS I wonder if I need to send preflight headers in an OPTION HTTP request.
So far I have tried:
Adding a vue.config.js file with dev server options ( I'll include the code below )
Using POSTMAN to construct the headers and pass a GET request - which works just fine
attempting to use the headers key in an Axios object ( code below )
My colleague who runs the PHP side of things assures me that all of the CORS headers in the files are correct.
I only have one component being loaded into App.vue called AxiosTest.
I've edited this post to update my findings.
By sending the headers as const the request is made as GET
const config = {
headers: {
"content-type": "application/vnd.api+json",
"Cache-Control": "no-cache",
"x-api-key": "9xxxxxxxxxxxxxxxxxxxxxx9"
}
}
axios.get(
`https://tunnel.xxxxx.com/api/headers.php?`,{ config
})
.then(response => {
this.results = response;
})
.catch(error => {
// eslint-disable-next-line
console.log(error)
})
And the header Response
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Mon, 08 Jul 2019 19:22:55 GMT
Content-Type: application/json; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Access-Control-Allow-Origin: http://54.x.x.155:8080
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 0
and the Request
Host: tunnel.xxxxxx.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:67.0) Gecko/20100101 Firefox/67.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: http://54.x.x.155:8080/
Origin: http://54.x.x.155:8080
DNT: 1
Connection: keep-alive
Cache-Control: max-age=0
However, if I keep the headers object inside of the axios.get function I get it sent as OPTIONS
axios.get(
`https://tunnel.xxxx.com/api/headers.php?`,{
headers: {
"content-type": "application/vnd.api+json",
"Cache-Control": "no-cache",
"x-api-key": "9xxxxxxxxxxxxxxxxxxxxxx9"
}
})
.then(response => {
this.results = response;
})
.catch(error => {
// eslint-disable-next-line
console.log(error)
})
Response
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Mon, 08 Jul 2019 19:22:55 GMT
Content-Type: application/json; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Access-Control-Allow-Origin: http://54.x.x.155:8080
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 0
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: {cache-control,x-api-key}
Request
Host: tunnel.xxxxx.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:67.0) Gecko/20100101 Firefox/67.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Access-Control-Request-Method: GET
Access-Control-Request-Headers: cache-control,x-api-key
Referer: http://54.x.x.155:8080/
Origin: http://54.x.x.155:8080
DNT: 1
Connection: keep-alive
Cache-Control: max-age=0
vue.config.js
module.exports = {
devServer: {
public: '54.x.x.x:8080',
proxy: 'https://tunnel.xxxxxxx.com/'
}
}
In the most successful test produced I still receive Invalid CORS origin or invalid API key.
Look at the documentation for axios:
axios.get(url[, config])
The get method takes two arguments but you are passing it three.
Thus the data you are trying to pass is being treated as configuration (and ignored because none of the values are valid config options) and the config data (including the request headers object) is ignored.
The query string needs to be part of the URL. Axios won't use the second argument to generate it for you.
const data = {
foo: "bar"
};
axios.get(
`https://example.com/api/headers.php?${new URLSearchParams(data)}`, {
headers: {
"Cache-Control": "no-cache",
"content-type": "application/vnd.api+json",
"x-api-key": "9xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx9"
}
}).then(response => {
console.log(response);
}).catch(error => {
console.log(error)
})
Had some problems with the formatting of my Axios call, and found that using headers as a const or var in my call did not work while dumping headers directly into the call did work.
On the PHP side, there were some extra curly brackets on the Access-Control-Allow-Headers directive that was causing the header response to be bracketed.
All in all it was troubleshooting through the Network tab in Browser Dev tools that helped us find the fix.
Here is the function that I'm calling at the top of the PHP scripts to allow the requester 100% full CORS access.
function InitCors() {
if (isset($_SERVER["HTTP_ORIGIN"])) {
header("Access-Control-Allow-Origin: {$_SERVER["HTTP_ORIGIN"]}");
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Max-Age: 0");
}
if ($_SERVER["REQUEST_METHOD"] == "OPTIONS") {
if (isset($_SERVER["HTTP_ACCESS_CONTROL_REQUEST_METHOD"])) header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
if (isset($_SERVER["HTTP_ACCESS_CONTROL_REQUEST_HEADERS"])) header("Access-Control-Allow-Headers: {" . $_SERVER["HTTP_ACCESS_CONTROL_REQUEST_HEADERS"] ."}");
}
header("Content-Type: application/json; charset=UTF-8");
}
I also have another test script to echo back all of the $_SERVER array values and I never see any of the custom headers when his Axios calls it. However, if you call things with curl from the command line (adding the headers) they most definitely do appear in the resulting output.
<?
//---------------------------------------------------------------------------------------------------
include("../dashboard/subs.php");
//---------------------------------------------------------------------------------------------------
if (! IS_SSL()) {
echo("{\"message\":\"API requires all traffic to be SSL encrypted.\"}\n");
exit;
}
//---------------------------------------------------------------------------------------------------
InitCors();
//---------------------------------------------------------------------------------------------------
$JSON = "{\"data\":[";
$JSON .= json_encode($_SERVER);
$JSON .= "]}";
echo("$JSON\n");
//---------------------------------------------------------------------------------------------------
?>

curl of css file only works if I execute the main page from browser

I'm trying to use cURL with PHP to retrieve CSS from this CSS file from archive
http://web.archive.org/web/20160312040057cs_/http://www.peer1.com/sites/all/modules/acro-custom/peer1_ribbonslider/peer1_ribbonslider.css?l
I am recieving this error :
HTTP/1.1 403 FORBIDDEN Server: Tengine/2.1.0 Date: Wed, 12 Apr 2017 12:30:04 GMT Content-Type: text/html; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive X-Archive-Wayback-Runtime-Error: RobotAccessControlException: Blocked by Robots X-Archive-Playback: 0 Content-Encoding: gzip
But After I execute the main page http://web.archive.org/web/20160312040057/https://www.peer1.com from browser , the curl request of that css file returns 200 OK.
I tried to use http://waybackmachinedownloader.com/ but I am facing the same problem.
Please advice.

HTTP POST 404 not found

I'm currently using Zapier to send some POST data from a TypeForm to a WordPress website to create a new user.
The POST works, I get all the variables in my script I need and a user is created.
For some reason though the POST on the zapier account or Hurl.it returns a 404 not found error. Both the domain and script are accessible and currently the only issue is that the client receives an email saying that his Zap may have an issue (because it's returning a 404). The zap test on the URL actually returns a success though.
It just seems strange that everything works but both zapier and hurl.it are returning a 404 not found error?
The request from hurl.it is:
Accept: */*
Accept-Encoding: gzip, deflate
Content-Length: 117
Content-Type: application/x-www-form-urlencoded
User-Agent: runscope/0.1
The response from hurl.it is:
Cache-Control: no-cache, must-revalidate, max-age=0
Content-Length: 7
Content-Type: text/html; charset=UTF-8
Date: Fri, 10 Jun 2016 10:57:04 GMT
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Pragma: no-cache
Server: Apache/2.4.7 (Ubuntu)
X-Powered-By: PHP/5.5.9-1ubuntu4.16
Anyone any ideas how I can resolve this?
Many thanks
I resolved this a few weeks ago but thought i'd just put it here in case anyone else comes across this.
The issue seemed to be with me requiring wp-blog-header.php in the file which was watching for the $_POST data. Now i'm pretty sure this was working fine at the start but i resolved this by changing the require to just be wp-load.php instead (i only needed access to a few functions).
Like i said above everything was still working with wp-blog-header.php being included it just 404ed on the zapier side and emailed the client. Something must of gone a miss in the wp() function or the template-loader.php file to cause it.

jQuery Ajax call just stopped working one day

Okay. I've found an answer to this on another StackOverflow post.
jQuery Ajax returning 404 Error, but correct Response
While that specific post assumes that my Wordpress installation may have been updated, the proposed solution worked to resolve my issue perfectly. Loading wp-load.php instead has resulted in the ajax calls working perfectly.
It's a shame that I found that answer only after creating this post!
I swear did my research :(
Below is the original question:
---------------------------------------------
A few months back, I have created a simple jQuery ajax call that pokes a php file to receive a small chunk of HTML back as response.
The call looks like this.
function ajaxTable() {
var request = $.ajax({
url: "/wp-content/themes/itul.theme.wp.abc/includes/download-ajax.php",
type: "POST",
dataType: "html",
data: { model: $('#download-model-select').find(':selected').data('id')}
});
request.done(function(msg) {
$("#download-table tbody").html(msg);
});
request.fail(function(jqXHR, textStatus) {
alert( "Request failed: " + textStatus );
});
}
The code has been working perfectly fine until about two days ago when someone noticed that the page had stopped working.
There had been absolutely no interaction with the code behind it, but all the jQuery ajax calls that I've been calling on the website had stopped working at that point. The code I've posted above is the simplest implementation of the various ajax calls hosted on the website.
For some reason, the calls kept flagging 404 errors despite the fact that going into the URL manually returns the results just fine! I had tried changing call type from POST to GET with no success either. Try going into the following URL, you'll see that the .php file is in place and pumping out the necessary response.
http://digital-watchdog.com/wp-content/themes/itul.theme.wp.abc/includes/download-ajax.php?model=856
After much frustration I went in to check the response headers, and viola! It seems that my ajax calls had been receiving the correct information all along! But why does it keep tagging 404 error?
I will paste the header information below. Please let me know if you've seen something like this happen before.
Thank you.
Remote Address:50.62.69.1:80
Request URL:http://digital-watchdog.com/wp-content/themes/itul.theme.wp.abc/includes/download-ajax.php?model=569
Request Method:GET
Status Code:404 Not Found
Request Headersview parsed
GET /wp-content/themes/itul.theme.wp.abc/includes/download-ajax.php?model=569 HTTP/1.1
Host: digital-watchdog.com
Connection: keep-alive
Accept: text/html, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36
Referer: http://digital-watchdog.com/support/download/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8,ko;q=0.6,es;q=0.4
Cookie: hsfirstvisit=http%3A%2F%2Fdigital-watchdog.com%2Fsupport%2Ftraining%2Fdw-spectrum-certification-san-francisco%2F|http%3A%2F%2Fdigital-watchdog.com%2Fwp-admin%2Fpost.php%3Fpost%3D1497%26action%3Dedit%26message%3D6|1392226058154; language=en; currency=USD; wp-settings-1=hidetb%3D1%26editor%3Dtinymce%26urlbutton%3Dnone%26imgsize%3Dfull%26align%3Dleft%26wordblock_category_tab%3Dpop%26libraryContent%3Dbrowse%26wplink%3D1%26ed_size%3D1042; wp-settings-time-1=1403654552; __utma=143756192.1546910067.1390588707.1403647017.1403708197.349; __utmb=143756192.6.10.1403708197; __utmc=143756192; __utmz=143756192.1401822249.292.9.utmcsr=hs_email|utmccn=(not%20set)|utmcmd=email; __hstc=74344461.64d6fa8253755804582ef98e557366d7.1392226058157.1403647017540.1403708204775.313; __hssrc=1; __hssc=74344461.6.1403708204775; hubspotutk=64d6fa8253755804582ef98e557366d7
Query String Parametersview parsed
model=569
Response Headersview parsed
HTTP/1.1 404 Not Found
Date: Wed, 25 Jun 2014 15:24:08 GMT
Server: Apache
X-Pingback: http://digital-watchdog.com/xmlrpc.php
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Cache-Control: no-cache, must-revalidate, max-age=0
Pragma: no-cache
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8

Display HTTP Response on Webpage using PHP

I am looking to put together a website that displays the full HTTP Request Headers and HTTP Response Headers for the loading of the page itself. For instance. If someone browses to http://example.com/index.php , I want the following to display:
HTTP Request
GET /index.php HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.16) Gecko/20110319 Firefox/3.6.16
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
HTTP Response
HTTP/1.1 200 OK
Date: Mon, 21 Dec 2011 10:20:46 GMT
Server: Apache/2.2.15 (Red Hat)
X-Powered-By: PHP/5.3.3
Content-Length: 1169
Connection: close
Content-Type: text/html; charset=UTF-8
We were able to get the Request header to display fairly simply using the following PHP code:
print $_SERVER['REQUEST_METHOD']." ".$_SERVER['REQUEST_URI']." ".$_SERVER['SERVER_PROTOCOL']."<br>";
foreach (apache_request_headers() as $name => $value)
echo "$name: $value<br>";
But are having some difficulties with the HTTP Response header. Anyone have any ideas of how we can do this? It does not have to be PHP if you have a method that works in Perle or CGI or whatever.
To be clear, I don't mean to set the HTTP Response to anything specific, only display the response served by the web server to load the page.
You want to use headers_list()
http://www.php.net/manual/en/function.headers-list.php
headers_list() will return a list of headers to be sent to the browser / client. To determine whether or not these headers have been sent yet, use headers_sent().
Well here is the issue, the response header is generated after the PHP (or any server-side language for that matter) has already completed its job.
To put it in english its like the post man handing you a letter and you asking him to explain how the process of handing you the letter went. He will probably just look at you dumb.
You will need a client-side language (ie. JavaScript) to perform this task.
Use PHP to get the headers sent to the web Server.
http://www.php.net/manual/en/function.apache-request-headers.php
Use JavaScript to get headers sent by the web server. I would suggest using jQuery for that.
http://api.jquery.com/jQuery.ajax/#jqXHR
This way you are sure that you get all the headers which are either received by the web server or the browser.
Check out get_headers in PHP Manual

Categories