Posting with XMLHttpRequest works only on same page

Website URL

NOTE - I’ve replaced all “.” with " DOT " and “:” with " COLON " to get around forum’s 2 link limit
MOD NOTE - Replaced DOT with . and COLON with : as I am getting confused

https://jonheard.net/personal/notes/?name=tst1

Error Message

No post data in header

Other Information

My ability to send post data using XMLHttpRequest changes depending on how relative the url is. When I’m at the page “jonheard.net/personal/notes/?name=tst1” and a JS XMLHttpRequest request is sent out with POST data, it seems to send a very different HTTP request header to the url “?act=sav” than to the url “…/notes?act=sav”, and the latter seems to remove POST data. This is strange as they both point to the same page as the request is coming from. Here’s a printout of “print_r(apache_request_headers())” for each case.

request to url “?act=sav”

Array
(
[Host] => jonheard.net
[X-Forwarded-Proto] => https
[X-Real-IP] => 216.212.2.117
[X-Forwarded-For] => 216.212.2.117
[Content-Length] => 31
[pragma] => no-cache
[cache-control] => no-cache
[sec-ch-ua] => “Not.A/Brand”;v=“8”, “Chromium”;v=“114”, “Google Chrome”;v=“114”
[sec-ch-ua-platform] => “Windows”
[sec-ch-ua-mobile] => ?0
[user-agent] => Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
[content-type] => application/x-www-form-urlencoded
[accept] => /
[origin] => https://jonheard.net
[sec-fetch-site] => same-origin
[sec-fetch-mode] => cors
[sec-fetch-dest] => empty
[referer] => https://jonheard.net/personal/notes/?name=tst1
[accept-encoding] => gzip, deflate, br
[accept-language] => en-US,en;q=0.9
[cookie] => __test=6c3e23a45d067b7348607783f6917590
)

Request to url “…/notes?act=sav”

Array
(
[Host] => jonheard.net
[X-Forwarded-Proto] => https
[X-Real-IP] => 216.212.2.117
[X-Forwarded-For] => 216.212.2.117
[pragma] => no-cache
[cache-control] => no-cache
[sec-ch-ua] => “Not.A/Brand”;v=“8”, “Chromium”;v=“114”, “Google Chrome”;v=“114”
[sec-ch-ua-platform] => “Windows”
[sec-ch-ua-mobile] => ?0
[user-agent] => Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
[accept] => /
[sec-fetch-site] => same-origin
[sec-fetch-mode] => cors
[sec-fetch-dest] => empty
[referer] => https://jonheard.net/personal/notes/?name=tst1
[accept-encoding] => gzip, deflate, br
[accept-language] => en-US,en;q=0.9
[cookie] => __test=6c3e23a45d067b7348607783f6917590
)

Any idea what might be triggering the removal of post data? I’m not on a proxy or anything.

By the way, if you need to try the site to see what I’m talking about. It’s a simple note taking page where you save by holding the mouse down until the screen becomes grey. Holding for extra long makes the screen light grey which will quit the note.

Never mind. It just started working :stuck_out_tongue:

1 Like

Well, actually no. The same thing is now happening if I POST to the url '‘https://jonheard.net/personal/notes?act=sav’.

FYI, this is a step in a process to be able to post between two pages in two directories.

Welcome Back!

If you are POSTing to a page on the same server (Now that I take a second look at your post, that looks like what you are trying to do >>>> ignore this post and see the one from Admin below

The reason why this is not working is because only web browsers are allowed to request your site, and we don’t allow API hosting here.

However, as you have a custom domain name, you can bypass this system by using Cloudflare:

6 Likes

Thanks! I’ve set up my site through cloudflare and am awaiting nameserver updates. It’s not clear how this will help sending POSTS between pages, but I’ll experiement and see what comes of it.

3 Likes

It sounds to me like you’re trying to do an AJAX request from one subdirectory of your site to another one. That should just work without having to use Cloudflare.

The first thing that comes to mind for me: please be aware that POST data is not persisted across redirects. If you try to POST to one URL, and that URL redirects you, then the redirected URL will be loaded as a GET request without any post data.

So if your site is using HTTPS and you have forced HTTPS redirects in place, but your script tries to post the data to the HTTP URL, you’ll see the request end up on your endpoint as a GET due to the redirect.

Right now, it looks a bit different, but I think that’s Cloudflare’s Automatic HTTPS Rewrite feature modifying your website, which changes the error and makes it harder to troubleshoot. I strongly recommend to disable that feature while using Cloudflare, a well configured website doesn’t need it.

6 Likes

It sounds to me like you’re trying to do an AJAX request from one subdirectory of your site to another one.

Yes, this is what I am trying to do. I’m not doing any redirects that I’m aware of, just a XMLHttpRequest straight to the page that should react to the post data. In fact, in trying to get this to work I’ve reduced the experiments to a page posting to itself. It works if I simply put in the variable part of the url (“?act=sav”), but if I put in more it seems to remove the post data. Or at least it did…

Yesterday I went through the cloudflare setup process. Now, when the page tries posting to itself, I always get the following error, regardless of how relative I make the url, even if it’s the full url starting with “https://”.

jonheard.net/:1 Mixed Content: The page at ‘https //jonheard net/personal/notes/?name=tst1’ was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint ‘http //jonheard net/personal/notes/?act=sav’. This request has been blocked; the content must be served over HTTPS.

I did a search, and “http” is nowhere on the page, while “https” is on the page when I do the XMLHttpRequest. I thought maybe XMLHttpRequest was forcing “http”, but it was working with SSL enabled before. Alternately, it seems like, maybe, cloud flare is turning my “https” url into “http”, and then I’m getting a complaint about that? It seems screwy, but it’s all I can come up with.

I just tried a minimal example of the issue (between folders) and everything worked fine. This is good as I can inch my way to the real scenario. I’ll post again if I hit another wall.

This issues seems to stem from XHR requests in JavaScript and the browser clearing the body when the request is made. Quite honestly, I don’t understand this, and JavaScript is not really my thing, so I’ll kind of just summarize what I found.

Running this HTTP request:

POST /personal/notes/?act=sav HTTP/1.1
Host: jonheard.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 42

name=tst1&text=Hey!%5CnIt's%20Greenreader9

The text does save (As can be shown by opening https://jonheard.net/personal/notes/?name=tst1)

I also (I don’t know how) got request.status to return 0 (Whatever that means, again, not a JS nerd)

I did find a few references to something that said that For POST requests, body is set to null by browsers. when using JS XHR. Nothing I found has an obvious solution (At least to me), or mentions mixed content errors as a side affect.


Also, thanks for the extra 7 tabs in my overloaded browser :joy:

4 Likes

Hey. Thanks for looking into this. I’m realizing that I shouldn’t be working on the same page that I’m posting for help on. I’ve put it into the bad state and will tinker with a copy of the page until this is resolved.

@Greenreader9
What you’ve posted is congruent with the working version (with the url being ‘?act=sav’). I’ve just set the url to ‘…/notes?act=sav’, so it should be breaking now.

2 Likes

I figured out what the problem was! I’m not sure as to the “why”, but here’s what happens:

When I am on an HTTPS page (I haven’t tested this on an HTTP page as cloudflare is locking me out of that atm), if I send my post with the FULL URL, INCLUDING the filename (such as “https://jonheard.net/personal/notes/index.php” for example), then the request is sent to HTTPS, and everything is fine. If I specify the URL WITHOUT the filename (such as “https://jonheard.net/personal/notes”) then it considers this an HTTP request, even when “https” is specified in the url. Before cloudflare, this resulted in an altered request header that was missing the POST payload. Once cloudflare was installed, this resulted in “blocked:mixed-content”.

I haven’t found any info on problems similar to this, but it’s pretty clear cut: add “index.php”, it works. Remove “index.php” and get “blocked:mixed-content”. Also, the scripts that failed before are posting fine now that I’ve added “index.php”.

2 Likes

That’s what I was referring to here.

That’s not really how things are supposed to work. Querying a URL that starts with http:// uses HTTP, and a URL that uses https:// uses HTTPS. Requests don’t switch between HTTP and HTTPS unless you specifically use URLs that refer to it (like you do with forced HTTPS redirects). The URL is irrelevant on a protocol level, it’s up to the code on the server to determine what to do with that.

If this solves the problem for you, then all it good. But the URL https://jonheard.net/personal/notes is a HTTPS URL, and won’t do anything with HTTP unless you make it so.

6 Likes

That’s not really how things are supposed to work.

Right? I was baffled too. However, I’ve made a simple page to demonstrate the issue here:
https://jonheard.net/demoHttpsIssue

note: this page writes it’s information to the console
note: I’ve disconnected cloudflare, so now I’m back to the original POST-with-no-payload bug

Interestingly, reviewing chrome’s dev tools in the network tab, I noticed that without including the filename in the url, the request gets an HTTP error of 301, which is described in wikipedia:

HTTP 301 is the HTTP response status code for 301 Moved Permanently. It is used for permanent redirecting, meaning that links or records returning this response should be updated.

It looks like requests without filenames are getting automatically re-directed, presumably by an infinityfree system, and this rewrites the POST request as a GET request, thus removing the POST data.

1 Like

Thank you! This is really helpful!

And I think I see the issue.

If you look at the network tab when clicking the “send without filename” button, you’ll see the first request goes to https://jonheard.net/demoHttpsIssue?act=send, which then redirects to https://jonheard.net/demoHttpsIssue/?act=send. What’s the difference? The redirect adds a trailing slash.

That’s normal when you make a request to a directory. A directory is typically identified with a trailing slash, so the server will add it if it doesn’t exist.

If I run the function post("https://jonheard.net/demoHttpsIssue/?act=send") from the console (the same function as being called on the page, but with the trailing slash already added), the POST request just works without any additional redirect.

Just to make sure that this wasn’t a free hosting quirk, I also tested this on a premium account, but I saw the same behavior there.

So to summarize, you don’t need the full file name, but you will need the trailing slash on the directory name.

I suppose it’s possible to change this behavior with .htaccess rules if you really want to.

5 Likes

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.