I was testing get and post requests in jsfiddle to better understand cors and csrf.
const data = { name: 'example', password: 'password'};
fetch('http://localhost:3001', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
.then((response) => response.json())
.then((data) => {
console.log('Success:', data);
})
.catch((error) => {
console.error('Error:', error);
});
const express = require('express')
const app = express()
app.get('/', (req, res) => {
res.send('Hi')
})
app.post('/', (req, res) => {
console.log('received')
res.send('Received')
})
app.listen(3001, () => {
console.log('Listening on port', 3001)
})
Is it normal that the first preflight request fails when doing a post request?
Also, shouldn't the successful preflight request happen before the post request? (On the server side, the code handling the post request isn't executed (nothing logged in console), which means that the browser cancelled the post request. How would the browser know not to follow through with the post request without waiting for the preflight request to complete first?)
Update:
Tried it using a simple html page instead of jsfiddle and the preflight request doesn't fail, but it still happens after the fetch request
Edit:
Only one options request is received on the server
// debugging middleware, should be first router handler of any kind
let requestCntr = 0
app.use((req, res, next) => {
let thisRequest = requestCntr++
console.log(
`${thisRequest}: ${req.method}, ${req.originalUrl}, `,
req.headers
)
// watch for end of theresponse
res.on('close', () => {
console.log(
`${thisRequest}: close response, res.statusCode = ${res.statusCode}, outbound headers: `,
res.getHeaders()
)
})
next()
})
Edit 2: from console
For a get request, no network error is shown in the Network tab, but the same error appears in the console except with a status code
It seems that Chrome simply displays the preflight request with a network error in the Network tab if it's related to csrf. Since opaque GET requests are fine, this doesn't happen for GET requests. So in the case of a post request, even if "preflight" shows up twice, it's the same preflight request.
Related
I am working on creating a user in Shopify by using the Admin and Storefront API build in my Next.js project. The user inputs an email and clicks "Sign up" which sends a post fetch request to my Next.js middleware. The post request fails and never sends back a response and the browser tab continuously circles like it is loading. Here is the API call belo. Why is it that the network tab of the inspector states "Pending"? I Thought .then() resolves a promise. Thank you for any help in advance.
export default function login(req: NextApiRequest, res: NextApiResponse) {
var myHeaders = new Headers()
myHeaders.append('Access-Control-Allow-Origin', '*')
myHeaders.append('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
myHeaders.append('Access-Control-Allow-Headers', 'Content-Type')
myHeaders.append('Content-Type', 'application/json')
myHeaders.append('Authorization', `${secretToken}`)
var raw = JSON.stringify({
customer: {
email: email,
accepts_marketing: true,
verified_email: true,
},
})
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw,
}
fetch('https://xxxxxxxxx.myshopify.com/admin/api/2022-10/customers.json', requestOptions)
.then((response) => response.text())
.then((result) => {
console.log("result - ",result)
res.status(200);
}).finally(() => {
console.log("Done")
})
.catch((error) => console.log('error', error))
"CAUTION: request is not finished yet"
I'm currently working on a project using a React frontend and an Express backend. Currently, when I make a GET request to retrieve data from the backend, everything is working fine. However, I'm unable to POST data to the backend and gain access to the data that's being sent. I'm getting an OK message so the request is going through, but when I log the request data in the backend, I get a message like this which is a jumble of random fields.
Here is the code snippit in the front end for the POST request
const makePost = (data) => {
fetch('http://localhost:5000/api', {
method: 'POST',
headers: {"Content-Type": "application/json", "Access-Control-Allow-Origin": "*"},
body: JSON.parse(JSON.stringify(data))
}).then(function(response){
console.log(response.text())
})
}
Here is my backend which handles the POST request
const express = require('express');
const app = express();
const cors = require('cors');
app.use(cors({
origin: '*'
}));
app.get('/api', (req,res) => {
res.json(menuItems);
});
app.post('/api', (req,res) => {
console.log(req)
})
app.listen(5000, () => console.log("server started on port 5000"));
In the code snippit above, console.log(req) is what was logged in the screenshot linked above.
In your Express server POST API, you are not returning any data, it may cause problems. This is a sample POST API using Axios, Express, React, and MongoDB.Hope it would help you.
//POST API
app.post('/services',async(req,res)=>{
const service = req.body;
const result = await servicesCollection.insertOne(service);
console.log(result);
res.send(result)
});
In client-side POST api:
const onSubmit = data => {
axios.post('http://localhost/services', data)
.then(res=>{
if(res.data.insertedId){
alert('data added successfully');
reset();
}
})
sample post API:
app.post('/book', (req, res) => {
const book = req.body;
// Output the book to the console for debugging
console.log(book);
books.push(book);
res.send('Book is added to the database');
});
Pls take a look at this link: https://riptutorial.com/node-js/example/20967/post-api-using-express
I am trying to develop the logic for a POST route handler in Express. I put the following together:
const headers = {
"Authorization":"TS Token asdfghjk-asdf-4567-fghjkl; tid=onfido-token";
"content-type": "application/json"
};
const params = {
"policy_request_id": "onfido_applicantandtoken"
};
app.get("/get_stuff", (req, res) => {
axios
.post("https://third/party/api", {
headers,
params
})
.then(function (response) {
res.json(response.data);
})
.catch(function (error) {
res.json("Error occured!");
});
}
});
I keep getting a 401 Unauthorized for the above. On Postman it works, but with the logic above I get a 401 Unauthorized, specifically in the logs I would get Header 'Authorization' not found or Could not parse authorization header. So I am unclear as to what could be going on with the header.
A lot of posts talk about req.headers, but my req.headers does not have the Authorization token and content-type in there, it has some other token that the API I am trying to connect to I assume needs to reach out to another API.
I have refactored it to look like this:
app.get("/get_stuff", (req, res) => {
axios
.post("https://third/party/api", params, headers)
.then(function (response) {
res.json(response.data);
})
.catch(function (error) {
res.json("Error occured!");
});
}
});
And I am still getting the same exact error.
To be clear the params is not something that gets passed into the URL on Postman, but rather the body of the postman request.
I was able to get it to successfully connect by declaring a global axios default like so:
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
as documented here:
https://www.npmjs.com/package/axios#user-content-config-defaults
I have a Vue.js application that uses axios to send request to ApiGee Server.
This is the code i use to send request to APIgee.
const headers = {
'X-API-Key': 'randomKey123123'
}
return axios({
method: 'get',
url: url,
headers: headers
}).then(response => {
console.log(response)
})
from the ApiGee, I can see OPTIONS request being received first since I done the request from the client side browser.
I can also see the X-API-Key header key but the value is missing.
The error I'm getting from the browser console is
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource
Below code helped me you can try this format:
created() {
// POST request using axios with set headers
const article = { title: "Vue POST Request Example" };
const headers = {
'X-API-Key': 'randomKey123123'
};
axios.post(url, article, { headers })
.then(response => console.log(response.data)
);
}
I tried to send data to line notify server by axios and it fail
I have tried 2 version of code. as shown below
version 1 :
axios({
method: "post",
url: "https://notify-api.line.me/api/notify",
data: 'message="from vue"',
config: {
headers: {
"Access-Control-Allow-Origin": "*",
"Content-Type": "multipart/form-data"
}
},
Authorization: "Bearer [my token]"
})
.then(function(response) {
console.log(response);
})
.catch(function(response) {
console.log(response);
});
response is
XMLHttpRequest cannot load https://notify-api.line.me/api/notify due to access control checks.
Error: Network Error
and version 2 is :
axios
.post("https://notify-api.line.me/api/notify", "message=from vue", {
headers: {
"Content-Type": "application/x-www-form-urlencoded",
Authorization: "Bearer [my token]"
}
})
.then(response => {
console.log(response);
});
response is
Preflight response is not successful
XMLHttpRequest cannot load https://notify-api.line.me/api/notify due to access control checks.
Error: Network Error
What wrong with is
but I have tried in postman it work fine
Oh I am too familiar with this. Heres an explanation on stackoverflow as to why your request works with postman but not in browser. Long story short browsers send a preflight options check that will ask the server if the action you're about to perform is allowed. Postman does not. Usually the "Access-Control-Allow-Origin": "*" header is sent by the server to the browser not the other way around.
Inside the docs for LINE Notify you can find:
POST https://notify-api.line.me/api/notify
Sends notifications to users or groups that are related to an access token.
If this API receives a status code 401 when called, the access token will be deactivated on LINE Notify (disabled by the user in most cases). Connected services will also delete the connection information.
Requests use POST method with application/x-www-form-urlencoded (Identical to the default HTML form transfer type).
My guess is that your access_token might have been deactivated. Try requiring a new access token and doing the request again.
I think it is impossible to connect directly to the external url for the axios cuz ajax is basically for the inner data network. But you might have a controller if you do a web project, so you can just use your controller language to make a connection with line notify. In my case, I made a rails project and used axios in the vue.js, so I made a link like this.
View(axios) => Controller(Ruby) => LineAPI
me currently work on this too.
I did my app with node js.
My way below is for your reference, it works well.
const axios = require('axios');
const querystring = require('querystring');
axios({
method: 'post',
url: 'https://notify-api.line.me/api/notify',
headers: {
'Authorization': 'Bearer ' + 'YOUR_ACCESS_TOKEN',
'Content-Type': 'application/x-www-form-urlencoded',
'Access-Control-Allow-Origin': '*'
},
data: querystring.stringify({
message: 'something you would like to push',
})
})
.then( function(res) {
console.log(res.data);
})
.catch( function(err) {
console.error(err);
});
I try it works.
async function test() {
const result = await axios({
method: "post",
url: "https://notify-api.line.me/api/notify",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"Authorization": "Bearer [token]",
},
data: 'message=你好哇'
})
.then((response) => {
console.log(response);
})
.catch((err) => {
console.log(err);
});
}
test();
I think you can check response on chrome debugger network.
or provide more information, thx.