CORS request 405 status code - javascript

Hello everyone please help me about my CORS problem
Im creating an API request from another domain my code below with an error,
var headers = {
host: host,
path: url + instance + '?action=reset',
method: 'POST'
};
var request = https.request(headers, function (response) {
logger('OCICompute', 'reset', 'INSTANCE', 'Got response from OPCAPI:' + response.statusCode);
res.header("Access-Control-Allow-Origin", "http://localhost:3000");
res.header("Access-Control-Allow-Methods", "OPTIONS, TRACE, GET, HEAD, POST, PUT");
res.header("Access-Control-Expose-Headers", "Origin, Content-Type, Authorization, Accept, X-Requested-With");
res.header("Access-Control-Allow-Credentials", "true");
res.header("Access-Control-Allow-Headers", "Origin, Content-Type, Authorization, Accept, X-Requested-With");
if (response.statusCode === 200) {
response.on('data', function (body) {
var data = JSON.parse(body);
res.json(data);
});
} else {
logger('OCICompute', 'reset', 'ERROR', 'stop fail');
res.json({'result': 'Fail'});
}
});
code above is on my module
and I have option in my main.
app.opts('/\.*/', function(req, res, next){
res.header("Access-Control-Allow-Origin", "http://localhost:3000");
res.header("Access-Control-Allow-Methods", "OPTIONS, TRACE, GET, HEAD, POST, PUT");
res.header("Access-Control-Expose-Headers", "Origin, Content-Type, Authorization, Accept, X-Requested-With");
res.header("Access-Control-Allow-Credentials", "true");
res.header("Access-Control-Allow-Headers", "Origin, Content-Type, Authorization, Accept, X-Requested-With");
res.send(200);
});
When I access this rest im getting this
405 error method not accepted and only got this
Host: api Url
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: */*
Accept-Language: ja,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate, br
Referer: http://localhost:3000/?root=compute
Authorization: Bearer Token
Origin: http://localhost:3000
Connection: keep-alive
Allow: OPTIONS
Connection: keep-alive
Content-Length: 58
Content-Type: application/json
Date: Tue, 24 Apr 2018 02:05:47 GMT
Server: LBAAS
Strict-Transport-Security: max-age=31536000; includeSubdomains;
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
I have another code which do exactly what I expected, the only difference is im using GET method. Above with error is POST.
var headers = {
host: host,
path: url + instance + '?action=reset',
method: **'GET'**
};
And here is the result
>
Host: api Url User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0)
> Gecko/20100101 Firefox/52.0 Accept: */* Accept-Language:
> ja,en-US;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate, br Referer:
> http://localhost:3000/?root=compute Authorization: Bearer Token
> Origin: http://localhost:3000 Connection: keep-alive
>
> Access-Control-Allow-Credentials: true Access-Control-Allow-Headers:
> Content-Type, Authorization, Accept, X-Requested-With
> Access-Control-Allow-Methods: OPTIONS, TRACE, GET, HEAD, POST, PUT
> Access-Control-Allow-Origin: http://localhost:3000
> Access-Control-Expose-Headers: Content-Type, Authorization, Accept,
> X-Requested-With Connection: keep-alive Content-Length: 2556
> Content-Type: application/json Date: Tue, 24 Apr 2018 02:05:57 GMT
> Server: LBAAS Strict-Transport-Security: max-age=31536000;
> includeSubdomains; X-Content-Type-Options: nosniff X-XSS-Protection:
> 1; mode=block
Here is my code on client side
self.stopButtonClick = function (event) {
console.log("停止ボタンが押されました");
var headers = {"Authorization": 'Bearer ' + self.ociComputeToken._latestValue};
$.ajax({
url: url,
type: "GET",
async: true,
headers: headers
}).done(function (data, textStatus, jqXHR) {
if (data.result !== 'Fail') {
self.compartmentHandler(self.compartmentId());
} else {
self.stopButtonClick(event);
}
}).fail(function (jqXHR, textStatus, errorThrown) {
console.log('サービスエラー');
self.stopButtonClick(event);
});
};

I just solve this one, and the problem is the url that im accessing is not correct, But then I got another error which is 502 bad gateway, GET is working fine, but what should I do when POST method is use?

Related

Why Set-Cookie is not stored?

I have following HTTP response:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: accept, authorization, content-type, origin, x-requested-with, user-agent, access-control-allow-origin, crossdomain, access-control-allow-credentials, x-requested-with
Access-Control-Allow-Methods: GET, POST, PUT, OPTIONS, DELETE, PATCH
Access-Control-Allow-Origin: https://speechifai-dashboard-fe.herokuapp.com
Access-Control-Max-Age: 600
Connection: keep-alive
Content-Length: 35
Content-Type: application/json; charset=utf-8
Date: Fri, 25 Feb 2022 05:52:17 GMT
Server: Cowboy
Set-Cookie: sessionIdSp=+5BtM+x+ZZ262Vs362qgUUmJE8PXd12G+AwMSdH14JQ=; Path=/; Secure; HttpOnly; SameSite=Lax
Link is here, you can try: https://speechifai-dashboard-fe.herokuapp.com/createPost
So frontend connect to backend, backend sends cookie, but I can not see under Cookies, why? What do I miss?
I have a Vapor backend:
It has following setting, what is wrong?
app.middleware.use(CORSMiddleware(configuration: .init(
allowedOrigin: .originBased,//.originBased,
allowedMethods: [.GET, .POST, .PUT, .OPTIONS, .DELETE, .PATCH],
allowedHeaders: [.accept, .authorization, .contentType, .origin, .xRequestedWith, .userAgent, .accessControlAllowOrigin, .init("crossDomain"), .accessControlAllowCredentials, .xRequestedWith],
allowCredentials: true
)), at: .beginning)
// Change the cookie name to "foo".
app.sessions.configuration.cookieName = cookieName
// Configures cookie value creation.
app.sessions.configuration.cookieFactory = { sessionID in
print("sessionID.string: \(sessionID.string)")
return .init(string: sessionID.string, isSecure: true, isHTTPOnly: true)
}
Calling here backend from React frontend:
axios({
method: "post",
url: "registerEmail",
data: {},
headers: {
"Content-Type": "application/json",
crossDomain: true,
},
})
.then((res) => {
dispatch(setGetUser(res.data));
})
.catch((err) => console.error(err));

CORS policy Issue, It works in local development, but it didn't work in deployed site

I'm having trouble with the CORS policy problem.
The project is very simple. I'm using the Sendgrid for sending e-mail.
I implemented frontend and backend for this tiny project. In backend, Sendgrid sending mail function is used.
I tested in local, it works fine. After I deployed the project, I got CORS issue.
This is the Error messages.
Access to fetch at 'https://mailsender-api.xxxxxx.xxx/sendmail' from origin 'https://mailsender-xxxxx.xxxxxx.xxx' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
POST https://mailsender-api.xxxxxx.xxx/sendmail net::ERR_FAILED
In frontend I separate fetch function
Fetch.tsx
export const fetchPost = async ({ endpoint, data }: any) => {
return fetch(`https://mailsender-api.xxxxxx.xxx/${endpoint}`, {
method: "POST",
body: JSON.stringify(data),
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
},
mode: "cors",
});
};
and different file calls the fetch function
const handleClick = async (
email: string,
subject: string,
intention: string
) => {
if (email === "" || intention === "") {
alert("Please fill out all fields");
} else if (!validateEmail(email)) {
alert("Invalid Email address");
} else {
const fetchOption = {
endpoint: `sendmail`,
data: {
email,
subject,
intention,
},
};
const result = await fetchPost(fetchOption);
if (result.ok) {
return history.push("/complete");
}
}
}
Below are backend code. I separate send mail function.
server.js
import cors from "cors";
import express from "express";
import { sendmail } from "./sendmail";
const router = express.Router();
const server = express();
server.use(
cors({
methods: ["GET", "POST", "OPTIONS"],
allowedHeaders: ["Content-Type", "Access-Control-Allow-Origin", "Accept"],
origin: "*",
credentials: true,
optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
})
);
server.use(express.json({ type: ["application/json"] })); // for parsing application/json
server.use(express.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
router.post("/sendmail", sendmail);
router.options("*", cors());
server.use(router);
server.listen(4000, function () {
console.log("app is listening");
});
export { router };
export default server;
when post requests comes in, sendmail function is invoked.
sendmail.js
import { sendScheduledMail } from "./config";
export const sendmail = async (req, res) => {
let data = {
address: req.body.email,
subject: req.body.subject,
content: req.body.intention,
};
try {
await sendScheduledMail(data.address, data.subject, data.content);
return res.end();
} catch (error) {
console.log(error);
}
};
Below is config.js file
import sgMail from "#sendgrid/mail";
import dotenv from "dotenv";
import "../.env";
dotenv.config();
export const sendScheduledMail = (address, subject, content) => {
let date = Math.round(new Date("June 29, 2020 12:37:00").getTime() / 1000);
let tempDate = Math.round(new Date().getTime() / 1000);
const email = {
from: "CBLM#CBLM.com",
to: address,
subject: subject,
html: `<p>${content}</p>`,
send_at: tempDate,
};
sgMail.setApiKey(process.env.SENDGRID_API_KEY);
return sgMail.send(email);
};
I deployed in Vercel.com. I asked about this problem, they said, it is codebase problem, so they have nothing to do. I searched for the solution, and I followed all they suggest, but it didn't work. Please help me.
------------------------UPDATED----------------------------------------
I deleted "Access-Control-Allow-Origin": "*", but it is not working.
I found out that Vercel has their own configure file ('now.json'). I added some headers, then I got something else.
now.json file
{
"routes": [
{
"headers": {
"Access-Control-Allow-Origin": "https://mailsender-delta.xxxxxx.xxx",
"Content-Type": "application/json",
"Access-Control-Allow-Methods": "POST, OPTIONS, HEAD",
"Access-Control-Allow-Headers": "Access-Control-Allow-Methods, Access-Control-Allow-Headers, Access-Control-Allow-Credentials, Access-Control-Allow-Origin, Content-Type",
"Access-Control-Allow-Credentials": "true"
},
"src": "/.*",
"dest": "/server.js"
}
]
}
I got POST https://mailsender-api.xxxxxx.xxx/sendmail net::ERR_ABORTED 405
Below is the request header
> General
Request URL: https://mailsender-api.xxxxxx.xxx/sendmail
Request Method: OPTIONS
Status Code: 204
Remote Address: 76.76.21.21:443
Referrer Policy: no-referrer-when-downgrade
> Response Headers
access-control-allow-credentials: true
access-control-allow-headers: Access-Control-Allow-Methods, Access-Control-Allow-Headers, Access-Control-Allow-Credentials, Access-Control-Allow-Origin, Content-Type
access-control-allow-methods: OPTIONS, GET, HEAD
access-control-allow-origin: *
cache-control: s-maxage=0
date: Fri, 03 Jul 2020 23:20:50 GMT
server: Vercel
status: 204
strict-transport-security: max-age=63072000; includeSubDomains; preload
x-vercel-cache: HIT
x-vercel-id: iad1::frndf-1593818450293-40ef1caa15b3
> Request Header
:authority: mailsender-api.xxxxxx.xxx
:method: OPTIONS
:path: /sendmail
:scheme: https
accept: */*
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9,ko;q=0.8,la;q=0.7
access-control-request-headers: access-control-allow-credentials,access-control-allow-headers,access-control-allow-methods,content-type
access-control-request-method: POST
origin: https://mailsender-delta.vercel.app
referer: https://mailsender-delta.vercel.app/
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: same-site
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
> General
Request URL: https://mailsender-api.xxxxxx.xxx/sendmail
Request Method: POST
Status Code: 405
Remote Address: 76.76.21.21:443
Referrer Policy: no-referrer-when-downgrade
> Response Headers
access-control-allow-credentials: true
access-control-allow-headers: Access-Control-Allow-Methods, Access-Control-Allow-Headers, Access-Control-Allow-Credentials, Access-Control-Allow-Origin, Content-Type
access-control-allow-methods: POST, OPTIONS, HEAD
access-control-allow-origin: https://mailsender-delta.vercel.app
cache-control: s-maxage=0
content-type: application/json
date: Fri, 03 Jul 2020 23:20:50 GMT
server: Vercel
status: 405
strict-transport-security: max-age=63072000; includeSubDomains; preload
x-vercel-cache: HIT
x-vercel-id: iad1::frndf-1593818450309-4f5547ab5464
> Request Headers
:authority: mailsender-api.xxxxxx.xxx
:method: POST
:path: /sendmail
:scheme: https
accept: */*
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9,ko;q=0.8,la;q=0.7
access-control-allow-credentials: true
access-control-allow-headers: X-Requested-With, Content-Type, Accept
access-control-allow-methods: *
content-length: 88
content-type: application/json
origin: https://mailsender-delta.xxxxxx.xxx
referer: https://mailsender-delta.xxxxxx.xxx/
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: same-site
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
I faced the same problem. The solution is available in the doc of vercel: https://vercel.com/support/articles/how-to-enable-cors .
In your node.js backend, create a file vercel.json and put the code there.
{
"headers": [
{
"source": "/api/(.*)",
"headers": [
{ "key": "Access-Control-Allow-Credentials", "value": "true" },
{ "key": "Access-Control-Allow-Origin", "value": "*" },
{ "key": "Access-Control-Allow-Methods", "value": "GET,OPTIONS,PATCH,DELETE,POST,PUT" },
{ "key": "Access-Control-Allow-Headers", "value": "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version" }
]
}
]
}
It works for sure.

Firefox Can't Read Fetch Response Header

I'm trying to use the fetch API to send requests in my application, and if I get a 401 Unauthorized response, I want to read the value of the WWW-Authenticate response header. This works fine on Chrome, but on Firefox, I'm unable to see the WWW-Authenticate header, even though it's included in the Access-Control-Expose-Headers header of my response.
My code:
const api = async (endpoint, fetchOptions) => {
// fetchOptions:
// {
// "credentials": "same-origin",
// "method": "GET",
// "headers": {
// "Accept": "application/json",
// "Content-Type": "application/json"
// }
// }
const response = await fetch(endpoint, fetchOptions)
.catch(r => r)
.then(r => { r.headers.forEach(console.log.bind(console)); return r; });
// handle 401 errors
if (!response.status === 401 && response.headers.has('WWW-Authenticate')) {
const authenticate = response.headers.get('WWW-Authenticate');
const authEndpoint = authenticate.match(/authorization_endpoint="([^"]+)/i)[1];
window.location.href = authEndpoint;
return;
}
};
My request:
GET /api/login HTTP/1.1
Host: localhost:3001
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0
Accept: application/json
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://localhost:3000/
Content-Type: application/json
Origin: http://localhost:3000
Connection: keep-alive
My response:
HTTP/1.1 401 Unauthorized
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json
Expires: -1
Server: Microsoft-IIS/10.0
Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Expose-Headers: WWW-Authenticate
WWW-Authenticate: Bearer realm="http://localhost:3001", authorization_endpoint="<oauth endpoint>"
Bearer
X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcYXNjaW50ZXJuXFNvdXJjZVxSZXBvc1xQb3J0YWxcQVBJXFNhbXMuV2ViQXBpXGFwaVxsb2dpbg==?=
Date: Wed, 12 Jun 2019 13:37:08 GMT
Content-Length: 128
Console output:
no-cache cache-control
application/json content-type
-1 expires
no-cache pragma
Does anyone know why Firefox wouldn't be able to read that response header?
There's a known bug with multiple WWW-Authenticate response headers, you might be hitting that: https://bugzilla.mozilla.org/show_bug.cgi?id=1491010.

fetch OPTIONS return HTTP 401 while Curl Command succeeds

This is what my fetch code looks like
let getSummary = (year, month) => {
let url = baseUrl + "/rest/monthlySummaries/" +
localStorage.getItem("paUserId") + "/" + year + "/" + month;
let authHeaders = {
"Content-Type": "application/json",
"Accept": "application/json",
"Bearer": localStorage.getItem("paToken")
};
console.log("summary url:", url, ",headers:", authHeaders);
return fetch(url, {
method: "GET",
headers: authHeaders
});
};
Since this is GET request, browsers make preflight reqeusts using HTTP OPTIONS to make sure that they make indeed make HTTP GET requests. I log what call is made, I see
summary url: https://api.myapp.com/rest/monthlySummaries/userId/2017/4 ,headers: Object {Content-Type: "application/json", Accept: "application/json", Bearer: "41afa8432aaa411e48b6c1c637c77cb3:userId:84000000"}Accept: "application/json"Bearer: "41afa8432aaa411e48b6c1c637c77cb3:userId:84000000"Content-Type: "application/json"__proto__: Object
2VM50885:1 OPTIONS https://api.myapp.com/rest/monthlySummaries/cca6b151-cab4-4de2-81db-9a739a62ae88/2017/4 401 (Unauthorized)
While, when I do similar thing on curl, everything works
curl -v -X OPTIONS -H"BEARER:e3310afc4dcd68d80d56a83bddfd4a09:userId:564000000" "https://api.myapp.com/rest/monthlySummaries/userId/2017/4"
* Trying 52.23.254.96...
* Connected to api.myapp.com (52.23.254.96) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
* Server certificate: DigiCert SHA2 High Assurance Server CA
* Server certificate: DigiCert High Assurance EV Root CA
> OPTIONS /rest/monthlySummaries/userId/2017/4 HTTP/1.1
> Host: api.myapp.com
> User-Agent: curl/7.43.0
> Accept: */*
> BEARER:e3310afc4dcd68d80d56a83bddfd4a09:userId:564000000
>
< HTTP/1.1 200 OK
< Date: Mon, 29 May 2017 23:21:11 GMT
< Server: WildFly/8
< X-Powered-By: Undertow/1
< Access-Control-Allow-Headers: origin, content-type, accept, authorization
< Allow: HEAD, GET, OPTIONS
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Credentials: true
< Content-Type: text/plain
< Content-Length: 18
< Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS, HEAD
< Access-Control-Max-Age: 1209600
< Vary: Accept-Encoding
<
* Connection #0 to host api.myapp.com left intact
Why the behavior is so different? What am I missing in fetch?
UPDATE
My server enables CORS support
#Provider
public class CORSFilter implements ContainerResponseFilter {
#Override
public void filter(ContainerRequestContext containerRequestContext,
ContainerResponseContext containerResponseContext) throws IOException {
containerResponseContext.getHeaders().add("Access-Control-Allow-Origin", "*");
containerResponseContext.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
containerResponseContext.getHeaders().add("Access-Control-Allow-Credentials", "true");
containerResponseContext.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
containerResponseContext.getHeaders().add("Access-Control-Max-Age", "1209600");
}
}
This can be seen in the response as well
See where you have configured
.add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
You haven't allowed the Bearer header, nor is it the correct way to pass a JWT.
You probably meant
"Authorization": `Bearer ${localStorage.getItem("paToken")}`
Sending Bearer when it isn't in the allowed headers list will fail the pre-flight validation.

CORS PUT: Not found with jQuery.ajax

I want to send some raw data to a subdomain of mine:
$.ajax({
url: "http://accounts.example.com:3000/me",
type: "PUT",
data: { wabo: "chabo" },
dataType: "json",
xhrFields: {
withCredentials: true
}
});
The browser now sends two requests:
OPTIONS to accounts.example.com:3000/me to check if CORS headers are valid
PUT to send data
The first one fails with HTTP 404 Not Found.
The CORS repsonse header looks valid:
HTTP/1.1 404 Not Found
X-Powered-By: Express
Access-Control-Allow-Origin: http://node.example.com:3000
Access-Control-Allow-Methods: HEAD, GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, X-Requested-With, Origin, Accept
Access-Control-Allow-Credentials: true
Content-Type: text/plain
Set-Cookie: connect.sid=s%3Aru8njoU2ZAnoKL2W2w%2B0BHF7.%2Fe%2FQI5f6NKRWQvWlcYEkMG7HHSxxj0haFDBUID2g45A; Domain=.example.com; Path=/
Date: Sun, 04 Nov 2012 11:31:22 GMT
Connection: keep-alive
Transfer-Encoding: chunked
In app.js of my node environment I have:
app.all('*', function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'http://node.example.com:3000');
res.header('Access-Control-Allow-Methods', 'HEAD, GET, POST, PUT, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, X-Requested-With, Origin, Accept');
res.header('Access-Control-Allow-Credentials', 'true');
next();
});
and
var me = require('./me');
app.get('/me', loadUser, me.show);
app.put('/me', loadUser, me.update);
GETting data from the subdomain is no problem only sending
Any idea what I have forgotten?
Regards, bodo
Try this instead:
app.all('*', function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'http://node.example.com:3000');
res.header('Access-Control-Allow-Methods', 'HEAD, GET, POST, PUT, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, X-Requested-With, Origin, Accept');
res.header('Access-Control-Allow-Credentials', 'true');
if( req.method.toLowerCase() === "options" ) {
res.send( 200 );
}
else {
next();
}
});

Categories

Resources