La demande suivante me donne une méthode 405 non autorisée lors de l'exécution à partir d'un projet généré par create-react-app simple à partir de localhost: 3000. J'ai vraiment besoin que cette application fonctionne en dehors du domaine (découplée). Cela ressemble beaucoup à un problème d'origine croisée, mais j'envoie le X-CSRF-TOKEN
jeton d'en-tête et Apache configuré pour accepter également les en-têtes.
Aucune idée de ce que je fais mal ...
Host: contenta.loc
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Access-Control-Request-Method: GET
Origin: http://localhost:3000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36
Access-Control-Request-Headers: authorization,x-csrf-token
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cependant, l'exécution du même code à partir d'un module personnalisé sur le même domaine s'exécute comme prévu.
import React, { Component } from 'react';
import axios from 'axios';
import Querystring from 'query-string';
import SubRequests from 'd8-subrequests';
const URL = 'http://contenta.loc';
class App extends Component {
state = {
csrfToken: '',
oauthToken: {}
};
constructor(props){
super(props);
this.initializeCsrfToken();
this.initializeOauthToken();
}
initializeCsrfToken(){
axios.get(URL + '/session/token')
.then(response => {
this.setState({csrfToken: response.data});
})
.catch((error) => {
console.log('error ' + error);
});
}
initializeOauthToken(){
const data = {
grant_type: 'password',
client_id: '77e40506-4b2a-4317-b6c0-5ed5b27ce886',
client_secret: 'test1123',
username: 'test',
password: 'test'
};
axios.post(URL + '/oauth/token', Querystring.stringify(data))
.then(response => {
this.setState({oauthToken: response.data.access_token});
})
.catch((error) => {
console.log('error ' + error);
});
}
fetchSubrequests() {
const subrequests = new SubRequests(URL + '/subrequests?_format=json');
const AuthStr = 'Bearer '.concat(this.state.oauthToken);
subrequests.add({
uri: '/api/categories'
});
subrequests.add({
uri: '/api/tags'
});
subrequests.add({
uri: '/api/menus'
});
axios.get(subrequests.getUrl(), {
headers: {
Authorization: AuthStr,
'X-CSRF-Token': this.state.csrfToken,
}
}).then(dataresponse => {
console.log(dataresponse);
})
}
render = () => {
return (
<button >
<div onClick ={
() => {this.fetchSubrequests()}
} > Fetch Subrequests</div>
</button>
)
}
}
export default App;
MISE À JOUR:
Voici ce que mon services.yml
cors.config ressemblait à: (CECI IS FAUX ???)
# Configure Cross-Site HTTP requests (CORS).
# Read https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
# for more information about the topic in general.
# Note: By default the configuration is disabled.
cors.config:
enabled: true
# Specify allowed headers, like 'x-allowed-header'.
allowedHeaders: ['x-csrf-token,authorization,content-type,accept,Origin,x-requested-with']
# Specify allowed request methods, specify ['*'] to allow all possible ones.
allowedMethods: ['POST, GET, OPTIONS, DELETE, PUT']
# Configure requests allowed from specific origins.
allowedOrigins: ['*']
# Sets the Access-Control-Expose-Headers header.
exposedHeaders: true
# Sets the Access-Control-Max-Age header.
maxAge: false
# Sets the Access-Control-Allow-Credentials header.
supportsCredentials: false
C'est ce que mon cors.config doit être pour que ça marche !!
cors.config:
enabled: true
# Specify allowed headers, like 'x-allowed-header'.
# ['x-csrf-token,authorization,content-type,accept,Origin,x-requested-with']
allowedHeaders: ['*']
# - '*'
# Specify allowed request methods, specify ['*'] to allow all possible ones.
# ['POST, GET, OPTIONS, DELETE, PUT']
allowedMethods: ['*']
# - '*'
# Configure requests allowed from specific origins.
allowedOrigins: ['*']
# Sets the Access-Control-Expose-Headers header.
exposedHeaders: true
# Sets the Access-Control-Max-Age header.
maxAge: false
# Sets the Access-Control-Allow-Credentials header.
supportsCredentials: false
Voici ce que mon Apache.conf
ressemble à:
<VirtualHost *:80>
ServerName loc
DocumentRoot /Users/justinwinter/Sites
VirtualDocumentRoot /Users/justinwinter/Sites/%-2/docroot
UseCanonicalName Off
Header set Access-Control-Allow-Origin "http://localhost:3000"
Header set Access-Control-Allow-Credentials true
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, PATCH, DELETE"
Header always set Access-Control-Allow-Headers: "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization"
<Directory "/Users/justinwinter/Sites/*/docroot">
AllowOverride All
Order allow,deny
Allow from all
Require all granted
</Directory>
AddType application/x-httpd-php .php
</VirtualHost>
NE FONCTIONNE PAS À PARTIR D'UNE APPLICATION JS REACT SÉPARÉE
La capture d'écran suivante montre le résultat de l'exécution du même JS à partir du domaine contenta.loc (même serveur que le point de terminaison)
TRAVAIL À PARTIR D'UN MODULE PERSONNALISÉ
La capture d'écran suivante montre l'erreur lors de l'exécution du JS à partir du serveur localhost create-react-app nodejs.
Vous pouvez activer la prise en charge de CORS en modifiant le fichier sites/default/services.yml
cors.config:
enabled: true
allowedHeaders:
- '*'
allowedMethods:
- '*'
allowedOrigins:
# Note: you need to specify the Host + port where your app will run.
- localhost:8000
exposedHeaders: false
maxAge: false
supportsCredentials: false
Essayez peut-être ['x-csrf-token', 'authorization', 'content-type', 'accept', 'Origin', 'x-requested-with']
au lieu.
Voici l'exemple de travail de local.services.yml
fichier qui peut être placé dans le sites/
dossier:
# Local development services.
#
# To activate this feature, follow the instructions at the top of the
# 'example.settings.local.php' file, which sits next to this file.
parameters:
http.response.debug_cacheability_headers: true
cors.config:
enabled: true
# Specify allowed headers, like 'x-allowed-header'.
allowedHeaders: ['*']
# Specify allowed request methods, specify ['*'] to allow all possible ones.
allowedMethods: ['*']
# Configure requests allowed from specific origins.
allowedOrigins: ['*']
# Sets the Access-Control-Expose-Headers header.
exposedHeaders: false
# Sets the Access-Control-Max-Age header.
maxAge: false
# Sets the Access-Control-Allow-Credentials header.
supportsCredentials: false
services:
cache.backend.null:
class: Drupal\Core\Cache\NullBackendFactory
Vérifier sites/default/default.services.yml
par exemple. Vérifiez également: prise en charge CORS opt-in .
Le fichier doit être chargé à partir de votre fichier de paramètres, par ex.
/**
* Enable local development services.
*/
$settings['container_yamls'][] = DRUPAL_ROOT . '/sites/local.services.yml';
Si vous utilisez Apache, vérifiez également: CORS sur Apache .