As the title says, I have a symfony3 Application with a rest api on a subdomain so that:
GET http://ajax.localhost.dev:10190/menus
returns a list of menus in JSON format.
Here is the configuration of the nelmio cors bundle (/app/config/nelmio/cors.yml)
nelmio_cors:
paths:
'^/':
origin_regex: true
allow_origin: ['^https?://%domain%:[0-9]+']
allow_headers: ['X-Custom-Auth']
allow_methods: ['POST', 'PUT', 'GET', 'DELETE', 'OPTIONS']
max_age: 3600
hosts: ['^ajax\.']
allow_credentials: true
I have been using this code:
export default class AppRemote extends Remote {
get host () { return `ajax.${super.host}`; }
open(xhr, data) {
if ("withCredentials" in xhr) {
xhr.open(data.method, this.url(data.url), true);
xhr.withCredentials = true; }
else if (typeof XDomainRequest != "undefined") {
xhr = new XDomainRequest();
xhr.open(data.method, this.url(data.url)); }
else { this.app.error('cannot init CORS Request'); }
return xhr;
}
};
which was working fine. Now I am trying to port it to the new fetch API and I am using this code:
const init = (url, method = 'GET') => {
return new Request(url, {
headers: new Headers({
'Access-Control-Allow-Credentials': true,
//'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods' : 'POST, GET, OPTIONS'
}),
mode: 'cors',
credentials: true,
method });
}
const get = (url) => {
return fetch(init(url));
}
It returns a 400 Bad Request, with Request Method: OPTIONS. If I just type the url in the browser, it works.
I guess there is some authentication issue, but just cannot figure out how to solve it. How can I do that?
After some research I finally found the mistake. Thanks to Firefox, which threw an error pointing me to the spot:
return new Request(url, {
//headers: new Headers({
//'Access-Control-Allow-Credentials': true,
//'Access-Control-Allow-Origin': '*',
//'Access-Control-Allow-Methods' : 'POST, GET, OPTIONS'
//}), //<-- working without headers at all
mode: 'cors',
credentials: 'include', //<-- that is the right setting
method });
Docs on MDN
Related
Hi there Guys i'm tryng to subscribe Firebase Cloud Messaging channels with provided token via capacitor/ioni app using PWA. But i got a CORS issue when i publish the www folder, instead on localhost it is working
This is the code im using in .ts file
this.devices = response;
FirebaseMessaging.requestPermissions().then(result => {
if(result.receive === 'granted')
{
FirebaseMessaging.getToken(
{
vapidKey: 'my-vapid-key',
}
).then( result => {
const token = result.token;
this.devices.forEach(i => {
let topic = i.serial
fetch('https://iid.googleapis.com/iid/v1/'+ token +'/rel/topics/'+ topic, {
method: 'POST',
headers: new Headers({
'Access-Control-Allow-Origin': '*',
"Access-Control-Allow-Methods": "DELETE, POST, GET, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization, X-Requested-With",
'Authorization': 'key=my-key'
})
}).then(response => {
alert('Fatto')
if (response.status < 200 || response.status >= 400) {
throw 'Error subscribing to topic: '+response.status + ' - ' + response.text();
}
console.log('Subscribed to "'+topic+'"');
}).catch(error => {
console.error(error);
})
})
this.addReceivedListener();
the error i faced is: "https://iid.googleapis.com/iid/v1/xxxxxxxxtokeeeen/rel/topics/mytopic' from origin 'https://mysite.site.com' 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."
there is no CORS on the other side, so we need to disable it and its working
I have already done this but Idk why when I try to apply it again in another code it does not work. So I have this code "Client side"
const response = await fetch("/api/ipfs", {method: "POST", DATA: "holaaaa"});
if (!response.ok) {
throw new Error(`Error: ${response.status}`);
}
const result = await response.json()
console.log(result.result)
And this one that is the "Server side"
function uploadIPFS(req, res) {
axios.get(req.body).then(r => {
let metadata = r.data
res.status(200).json({ metadata: metadata });
}).catch(err => console.error(err))
}
export default function handler(req, res) {
if (req.method==='POST') {
uploadIPFS(req, res);
}
}
This is working with another api file I have, so I implement another file that is this one and in another function of the client side make a call to the new api file, the problem is that the variable I want to pass from client to server is the body one, the one that says "holaaaa", is it not working and it throws this error.
API resolved without sending a response for /api/ipfs, this may result in stalled requests.
Error: Cannot read properties of null (reading 'replace')
at dispatchHttpRequest (C:\Users\berna\Desktop\Programming\Web development\BlueToken\bluetoken\node_modules\axios\lib\adapters\http.js:161:23)
at new Promise (<anonymous>)
at httpAdapter (C:\Users\berna\Desktop\Programming\Web development\BlueToken\bluetoken\node_modules\axios\lib\adapters\http.js:49:10)
at dispatchRequest (C:\Users\berna\Desktop\Programming\Web development\BlueToken\bluetoken\node_modules\axios\lib\core\dispatchRequest.js:58:10)
at Axios.request (C:\Users\berna\Desktop\Programming\Web development\BlueToken\bluetoken\node_modules\axios\lib\core\Axios.js:109:15)
at Axios.<computed> [as get] (C:\Users\berna\Desktop\Programming\Web development\BlueToken\bluetoken\node_modules\axios\lib\core\Axios.js:131:17)
at Function.wrap [as get] (C:\Users\berna\Desktop\Programming\Web development\BlueToken\bluetoken\node_modules\axios\lib\helpers\bind.js:9:15)
at uploadIPFS (webpack-internal:///(api)/./pages/api/ipfs.js:17:11)
at handler (webpack-internal:///(api)/./pages/api/ipfs.js:37:9)
at Object.apiResolver (C:\Users\berna\Desktop\Programming\Web development\BlueToken\bluetoken\node_modules\next\dist\server\api-utils\node.js:184:15) {
config: {
transitional: {
silentJSONParsing: true,
forcedJSONParsing: true,
clarifyTimeoutError: false
},
adapter: [Function: httpAdapter],
transformRequest: [ [Function: transformRequest] ],
transformResponse: [ [Function: transformResponse] ],
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
env: { FormData: [Function] },
validateStatus: [Function: validateStatus],
headers: {
Accept: 'application/json, text/plain, */*',
'User-Agent': 'axios/0.27.2'
},
method: 'get',
url: '',
data: undefined
},
url: '',
exists: true
}
any idea abt this?
The request to your API is made, but you are not adding anything to the request body. I think you need to change your DATA property in your fetch call to body:
const response = await fetch("/api/ipfs", { method: "POST", body: "holaaaa" });
Also, since you are passing that body parameter to the axios.get() method in your API handler, I assume it's supposed to be a URL?
I am trying to delete an element from client side. I am using script setup and on onMounted hook the request works fine, but when i try to run the same code on event click, it throws me an error
onMounted(() => {
const { data, pending, error, refresh } = await useFetch(
'https://example.com/api/api-request',
{
method: 'DELETE',
}
)
})
on clcik event throws an error
const testDelete = async() => {
const { data, pending, error, refresh } = await useFetch(
'https://example.com/api/api-request',
{
method: 'DELETE',
headers: {
"Accept": "*/*",
"Access-Control-Allow-Methods": "*"
},
}
)
}
Access to fetch at 'https://example.com/api/api-request' from origin 'http://localhost:3000' has been blocked by CORS policy: Method DELETE is not allowed by Access-Control-Allow-Methods in preflight response.
https://example.com/api/api-request is just example, with Postman request works fine and element is deleted.
[ A CORS policy error ]
[ Gridsome as front and Axios for HTTP requests ]
[ WP-Graphql v1.6.7 ]
[ WPGraphQL Cors installed ]
[Access to XMLHttpRequest at ''https://my_wp_backend.com' from origin 'http://my_gridsome_front.com' 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.]
Axios request
addComment() {
axios({
url: 'https://my_wp_backend.com',
method: 'post',
headers: {
'Access-Control-Allow-Origin': '*',
},
withCredentials: true,
data: {
query: `mutation CREATE_COMMENT {
createComment(input: {
commentOn: 329,
content: "Lorem ipsum",
author: "John"
}) {
success
comment {
id
content
author {
node {
name
}
}
}
}
}`
}
})
.then(res => {
console.log(res.data);
})
.catch(err => {
console.log(err.message);
});
}
I've added a filter to my theme too
add_filter(
'graphql_response_headers_to_send',
function( $headers ) {
$headers['Access-Control-Allow-Origin'] = 'https://my_gridsome_front.com';
return $headers;
}
);
in WPGraphQL Cors settings, Add Site Address to "Access-Control-Allow-Origin" header = Checked
I still cant get over the CORS error after installing CORS plugin, following all instructions in docs and going through all related repo issues.
Any hints is very much appreciated.
I am currently trying to catch posted values from form inside specific route rule.
Since all the other SO posts about this do not work I wanted to ask again.Do you have this sorted out and implemented in your projects?
Is there a solution for Iron-Router#1.0.9?
this.request.body
Above code inside route rule always returns undefined.
Router.route('/register', function(){
console.log( JSON.stringify(this.request.body) );
//this.render('test',{data:{data:this.request.body.username}})
});
//SERVER ONLY
if (Meteor.isServer) {
Meteor.methods({
'addSong': function(songName) {
var userId = Meteor.userId()
songs.insert({
userId: userId,
name: songName
})
}
})
Router.onBeforeAction(Iron.Router.bodyParser.urlencoded({
extended: true
}));
}
The iron router guide lets us know that this.request and this.response are "NodeJS request and response objects".
If you take a look at some documentation for req.body, you will find that:
By default, it is undefined, and is populated when you use
body-parsing middleware such as body-parser and multer.
From Iron-router's guide:
IR makes express' body-parser available at Iron.Router.bodyParser.
So there you have it! If you want this.request.body to be populated, you should maybe add:
Router.onBeforeAction(Iron.Router.bodyParser.urlencoded({
extended: true
}));
I have created one file for my controller to maintain code re-usability name as solar.js under controller folder that solar file has my db functionality and pass the request and response as parameter for that file like exports.getSolarInfo = (req,res) => { console.log(req.body) }, here your will get ur body paramter.then manipulate our functionality here then send response like response = { "status" : 0, "result" : "invalid query" } res.end(JSON.stringify(response));
// importing controller
const SOLAR = require('./controllers/solar.js');
Router.route( '/solar', function() {
//setting header type to allow cross origin
this.response.setHeader( 'Access-Control-Allow-Origin', '*' );
if ( this.request.method === "OPTIONS" ) {
this.response.setHeader( 'Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept' );
this.response.setHeader( 'Access-Control-Allow-Methods', 'POST, PUT, GET, DELETE, OPTIONS' );
this.response.end( 'Set OPTIONS.' );
} else {
SOLAR.getSolarInfo(this.request,this.response);
}
}, { where: 'server' });