My aim is to run my Quasar app to other devices connected to the Local Area Network. I managed to run them as expected although, when I was logging in to the website, I am having this error POST http://10.0.0.20:8080/MyComposer/?submitId=3 404 (Not Found) despite working
fine on my localhost before. Why is it not reading the Classes in my index.php at the backend folder properly?
P.S. I don't know if this could solve my problem but when I used phpinfo() to debug, I noticed that the REQUEST_METHOD there is GET instead of POST. Is it possible to swap them? I'll try whatever you guys give me.
Console
General
Request URL: http://10.0.0.20:8080/MyComposer/?submitId=3
Request Method: POST
Status Code: 404 Not Found
Remote Address: 10.0.0.20:8080
Referrer Policy: no-referrer-when-downgrade
Response Headers
Connection: keep-alive
Content-Length: 151
Content-Security-Policy: default-src 'none'
Content-Type: text/html; charset=utf-8
Date: Tue, 28 Jul 2020 12:18:12 GMT
Vary: Accept-Encoding
X-Content-Type-Options: nosniff
X-Powered-By: Express
Request Headers
Accept: application/json, text/plain,
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,es;q=0.8
Connection: keep-alive
Content-Length: 49
Content-Type: application/json
Host: 10.0.0.20:8080
Origin: http://10.0.0.20:8080
Referer: http://10.0.0.20:8080/
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36
Headers.php
<?php
header('Access-Control-Allow-Origin: http://10.0.0.20:8080/'); //OR EITHER http://10.0.0.20:8080/ OR .$_SERVER['HTTP_ORIGIN']
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Max-Age: 3600');
if (strtoupper($_SERVER['REQUEST_METHOD']) === 'OPTIONS') {
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
exit(0);
}
store.js
actions: {
LOGIN (context, payload) {
return new Promise((resolve, reject) => {
axios
.post('/MyComposer/', payload, {
headers: { 'Content-Type': 'application/json' },
params: {
submitId: 3
}
})
index.php
<?php
require 'Classes/Headers.php';
require 'vendor/autoload.php';
echo 'Hello!';
phpinfo();
use Classes\SubjectClass;
use Classes\TestClass;
use Classes\AnswerClass;
use Classes\LoginClass;
use Classes\RegisterClass;
use Classes\TeacherClass;
use Classes\StudentClass;
use Classes\AccountClass;
use Classes\AccessClass;
use Classes\SchoolClass;
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$addsubject = new SubjectClass();
$addsubject->addSubject();
$addtest = new TestClass();
$addtest->addTest();
$submitTest = new AnswerClass();
$submitTest->submitTest();
$submitLoginData = new LoginClass();
$submitLoginData->submitLoginData();
$addAccountData = new RegisterClass();
$addAccountData->addAccountData();
$addSchool = new SchoolClass();
$addSchool->addSchool();
}
The problem was caused not by a coding error but due to two webservers being installed on the affected system, a XAMPP installation running on the default port 80 and a Node.Js server running on port 8080.
To diagnose the problem we first copypasted the URL being used in the script into a browser window which gave the same 404 HTTP error. This excluded the option that the axios.post() method caused the behavior.
Next the basic HTTP port assignment was tested. Calling the address http://10.0.0.20 (user's IP inside the local network) gave the correct XAMPP homepage. When checking the httpd.conf and in it the Listen setting (which should have been Listen 8080) we saw the Apache was using the default HTTP port isntead. Changing it to 8080 (as was used in the script) and restarting Apache resulted in the server not starting with the error:
Problem detected! Port 8080 in use by "C:\Program
Files\nodejs\node.exe" with PID 3808! Apache WILL NOT start without
the configured ports free! You need to uninstall/disable/reconfigure
the blocking application or reconfigure Apache and the Control Panel
to listen on a different port.
It was now sure that messed up ports were the cause of the problem. Removing the :8080 from the scripts made sure the requests were sent to the right server.
Related
I have a socket.io server setup on an AWS EC2 instance. I am able to connect fine, as are most people, but I'm running into an issue with a couple of users where the HTTP protocol version is undefined. I have supplied two requests to my socket io server, one with an expected HTTP version, and one where it is undefined. It seems that otherwise the requests are the same, which leads me to believe that the HTTP version is the problem.
GET Request that is working fine (removed specific ip/website info)
GET /socket.io/?EIO=3&transport=polling&t=Nit_A4F HTTP/1.1
Host: {{My EC2 Host:Port}}
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: {{My Website}}
Connection: keep-alive
Referer: {{My Website}}
GET Request that is failing (Note line 1, where the HTTP version is undefined, rather than HTTP/1.1)
GET /socket.io/?EIO=3&transport=polling&t=Nit_UGj undefined
Host: {{My EC2 Host:Port}}
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: {{My Website}}
Connection: keep-alive
Referer: {{My Website}}
Pragma: no-cache
Cache-Control: no-cache
There's a couple of questions in this problem, really. First, is the undefined HTTP protocol version a common or reasonable use case? If so, is there a way I can manually set the HTTP protocol version on the frontend (Angular), or set up CORS to handle the undefined HTTP protocol version on the backend?
If the undefined HTTP protocol version is not a reasonable use case, is there anything these users can do to fix it?
Here is my current socket.io setup on the backend with CORS:
const io = require('socket.io')(server, {
cors: {
origin: '*',
methods: ['GET', 'POST'],
transports: [ 'websocket', 'polling' ],
credentials: true,
}
});
I don't have much on my frontend besides just connecting to the correct url, but here it is just in case:
export class SocketIOService {
private socket: io.Socket;
constructor() {
this.socket = io(
environment.socketUrl
);
}
sendData(socketEvent: string, data: any) {
this.socket.emit(socketEvent, data);
}
getData(socketEvent: string) {
return new Observable(observer => {
this.socket.on(socketEvent, msg => {
console.log("handling event");
observer.next(msg);
});
});
}
}
Any help here would be appreciated.
For anyone looking for an answer as to why this specific problem occurs, I can't say I have an answer.
The solution that was applicable to me to solve my issue was to upgrade my frontend and backend to communicate through https instead of http.
I have a ReactJS client running webpack-dev-server on localhost:3000. It connects to a Hapi API server on localhost:8080 and I'm trying to provide a basic cookie using hapi-auth-jwt2 (I've also tried hapi-auth-cookie with equal results).
I can see the response header provides a valid set-cookie header and everything looks okay, but all my browser tests ignore it and the cookie is never set (verified by checking document.cookie and using the browser tools like Chrome's Application tab). When I connect directly to the API server with Postman, it picks up the set-cookie header correctly and stores it so I think it's just some kind of domain/port/host configuration issue.
As a simple test, I tried deploying to our ec2 environment but that didn't help. The ec2 environment is similar, with one instance serving the client and another instance serving the API. I've also tried modifying my local hosts file to redirect a domain like 127.0.0.1 example.com and providing the domain=.example.com field in the cookie, but that also didn't help.
I think I'm just missing something basic but I don't know what it is. See below for response/request headers on login.
Request Headers
POST /login HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Content-Length: 47
Accept: application/json, text/plain, */*
Origin: http://localhost:3000
Authorization: undefined
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36
Content-Type: application/json
Referer: http://localhost:3000/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Response Headers
HTTP/1.1 200 OK
authorization: <jwt token>
vary: origin,accept-encoding
access-control-allow-origin: http://localhost:3000
access-control-allow-credentials: true
access-control-expose-headers: WWW-Authenticate,Server-Authorization
content-type: application/json; charset=utf-8
set-cookie: cookie=token; Max-Age=604800; Expires=Wed, 16 May 2018 21:11:23 GMT; SameSite=Lax; Path=/
cache-control: no-cache
content-encoding: gzip
Date: Wed, 09 May 2018 21:11:23 GMT
Connection: keep-alive
Transfer-Encoding: chunked
http-proxy-middleware, which webpack-dev-server uses, has options for cookie domain/path rewrites.
You should see if those satisfy your needs. Otherwise you can also manually parse and reset cookies in the onProxyRes callback. Here is an example.
I have an ajax file upload using (Dropzone js). which sends a file to my hapi server. I realised the browser sends a PREFLIGHT OPTIONS METHOD. but my hapi server seems not to send the right response headers so i am getting errors on chrome.
here is the error i get on chrome
XMLHttpRequest cannot load http://localhost:3000/uploadbookimg. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access.
this is the hapi js route handler
server.route({
path: '/uploadbookimg',
method: 'POST',
config: {
cors : true,
payload: {
output: 'stream',
parse: true,
allow: 'multipart/form-data'
},
handler: require('./books/webbookimgupload'),
}
});
In my understanding hapi js should send all cors headers from the Pre-fight (OPTIONS) request.
Cant understand why its is not
Network request /response from chrome
**General**
Request Method:OPTIONS
Status Code:200 OK
Remote Address:127.0.0.1:3000
**Response Headers**
view parsed
HTTP/1.1 200 OK
content-type: application/json; charset=utf-8
cache-control: no-cache
vary: accept-encoding
Date: Wed, 27 Apr 2016 07:25:33 GMT
Connection: keep-alive
Transfer-Encoding: chunked
**Request Headers**
view parsed
OPTIONS /uploadbookimg HTTP/1.1
Host: localhost:3000
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Access-Control-Request-Method: POST
Origin: http://localhost:4200
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.87 Safari/537.36
Access-Control-Request-Headers: accept, cache-control, content-type
Accept: */*
Referer: http://localhost:4200/books/upload
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Thanks in advance
The hapi cors: true is a wildcard rule that allows CORS requests from all domains except for a few cases including when there are additional request headers outside of hapi's default whitelist:
["accept", "authorization", "content-type", "if-none-match", "origin"]
See the cors option section in the API docs under route options:
headers - a strings array of allowed headers ('Access-Control-Allow-Headers'). Defaults to ['Accept', 'Authorization', 'Content-Type', 'If-None-Match'].
additionalHeaders - a strings array of additional headers to headers. Use this to keep the default headers in place.
Your problem is that Dropzone sends a couple of headers along with the file upload that aren't in this list:
x-requested-with (not in your headers above but was sent for me)
cache-control
You have two options to get things working, you need to change something on either the server or the client:
Option 1 - Whitelist the extra headers:
server.route({
config: {
cors: {
origin: ['*'],
additionalHeaders: ['cache-control', 'x-requested-with']
}
},
method: 'POST',
path: '/upload',
handler: function (request, reply) {
...
}
});
Option 2 - Tell dropzone to not send those extra headers
Not possible yet through their config but there's a pending PR to allow it: https://github.com/enyo/dropzone/pull/685
I want to add my 2 cents on this one as the above did not fully resolve the issue in my case.
I started my Hapi-Server at localhost:3300. Then I made a request from localhost:80 to http://localhost:3300/ to test CORS. This lead to chrome still blocking the ressource because it said that
No 'Access-Control-Allow-Origin' header is present on the requested
resource
(which was not true at all).
Then I changed the XHR-Request to fetch the url to a url for which I actually created a route inside HapiJS which - in my case - was http://localhost:3300/api/test. This worked.
To overgo this issue I created a "catch-all" route in HapiJS (to overgo the built-in 404 catch).
const Boom = require('Boom'); //You can require Boom when you have hapi
Route({
method: '*',
path: '/{any*}',
handler: function(request, reply) {
reply(Boom.notFound());
}
})
I would like to set-up a basic HTTP-Authentication using JQuery on the client-side and Node.js on the server side.
I have made the following Ajax request on the server side to set the headers:
$.ajax({
type: "GET",
url: URL_SLACK_SERVER,
dataType: "json",
beforeSend: function(xhr){
xhr.setRequestHeader("Authorization", "Basic " +btoa("username:xxx") );
},
success:function(rsp){
filterMessages(rsp);
}
});
Which I want to use on my server side using the basic-auth module:
var express = require('express');
var bodyParser = require('body-parser');
var auth = require('basic-auth');
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Authorization, Accept, Key");
var cre = +auth(req);
console.log('Auth: ' +cre.username);
next();
});
But, doing this way, I encounter some issues:
I do not see that the header are set in the preflight OPTIONS HTTP request:
OPTIONS /server HTTP/1.1
Host: server.com
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: null
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111
Safari/537.36
Access-Control-Request-Headers: accept, authorization
Accept: /
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,fr;q=0.6
I got the following error, which I do not understand well:
Request header field Authorization is not allowed by
Access-Control-Allow-Headers in preflight response.
Also, please note that the call from the client to the server is a cross-domain call, that's why there is these set headers written on the Node.js file.
How can I efficiently perform this basic HTTP-Authentication?
Since your client and server are running on different domains, you need to configure the CORS header in your server to make it work.
You need to set the header "Access-Control-Allow-Origin:http://foo.example" or "Access-Control-Allow-Origin:*" in your server.
Yes its a cors problem.
When you enable cors in npm (Look for cors module and append it via npm) you can set a specific domain that is allowed. When you set this the basic authentication header will be send with the request.
Look at this request:
https://stackoverflow.com/a/18511690/3232739
I'm trying to do a cross-domain POST with jQuery using CORS, but after the OPTIONS request is sent (and responded to), the POST doesn't happen. My request/response filters are shown below. My jQuery post code is also shown. It looks like the response has the proper CORS response headers, so I'm not sure why this isn't working.
var params = {};
params.data = myPostData;
params.headers = {
'x-pingother' : 'pingpong'
};
$.ajax(params);
Request Header
OPTIONS /my/service/url HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:17.0) Gecko/20100101 Firefox/17.0
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
Connection: keep-alive
Origin: http://localhost:9876
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type,x-pingother
Pragma: no-cache
Cache-Control: no-cache
Response Header:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://localhost:9876
Access-Control-Allow-Methods: POST,GET,OPTIONS
Access-Control-Allow-Headers: x-pingother
Content-Length: 703
Content-Type: application/vnd.sun.wadl+xml
Allow: OPTIONS,POST
Last-Modified: Sat, 19 Jan 2013 13:46:51 EST
Server: Jetty(6.1.25)
I'm running automated tests from a local server (JSTestDriver) that connects to a web server running on a different port. The web server runs on 8080 and the page making the request runs on 9876.
This was solved by adding the response headers as specified in
jQuery CORS request not working when sending Range request
Did you try to explicitly tell jQuery to enable cors?
$.support.cors = true;