405 ошибка react

Attribute routing is enabled, according to the screenshot posted in comments, as the WebApiConfig has the default configuration

public static class WebApiConfig {
    public static void Register(HttpConfiguration config) {
        // Attribute routing.
        config.MapHttpAttributeRoutes();

        // Convention-based routing.
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

Note the api prefix on the convention based route.

The request from client is being made to /SiteCollections/CreateModernSite which wont match the Web API as the API controller appears to not be using the attribute routing and the requested URL does not match the Web API convention based route.

Also on the client side a JSON body is constructed in options while the content type is set to 'multipart/form-data'

If the intention is to POST content in the body, then on the server side you would need to make a few changes to make the API accessible.

[Authorize]
[RoutePrefix("api/SiteCollections")]
public class SiteCollectionsController : ApiController {
    // GET api/SiteCollections
    [HttpGet]
    [Route("")]
    public async Task<IHttpActionResult> Get() {
        var tenant = await TenantHelper.GetTenantAsync();
        using (var cc = new OfficeDevPnP.Core.AuthenticationManager().GetAppOnlyAuthenticatedContext(tenant.TenantAdminUrl, tenant.ClientId, tenant.ClientSecret)) {
            var tenantOnline = new Tenant(cc);
            SPOSitePropertiesEnumerable siteProps = tenantOnline.GetSitePropertiesFromSharePoint("0", true);
            cc.Load(siteProps);
            cc.ExecuteQuery();
            var sites = siteProps.Select(site => 
                new TenantManagementWebApi.Entities.SiteCollection() {
                    Url = site.Url,
                    Owner = site.Owner,
                    Template = site.Template,
                    Title = site.Title
                })
                .ToList();
            return Ok(sites);
        }
    }

    // POST api/SiteCollections
    [HttpPost]
    [Route("")]
    public async Task<IHttpActionResult>  CreateModernSite([FromBody]NewSiteInformation model) {
        if(ModelState.IsValid) {
            var tenant = await TenantHelper.GetTenantAsync();
            using (var context = new OfficeDevPnP.Core.AuthenticationManager().GetAppOnlyAuthenticatedContext(tenant.TenantAdminUrl, tenant.ClientId, tenant.ClientSecret)) {
                 var teamContext = await context.CreateSiteAsync(
                    new TeamSiteCollectionCreationInformation {
                        Alias = model.Alias, // Mandatory
                        DisplayName = model.DisplayName, // Mandatory
                        Description = model.Description, // Optional
                        //Classification = Classification, // Optional
                        //IsPublic = IsPublic, // Optional, default true
                    }
                );
                teamContext.Load(teamContext.Web, _ => _.Url);
                teamContext.ExecuteQueryRetry();
                //204 with location and content set to created URL
                return Created(teamContext.Web.Url, teamContext.Web.Url);
            }
        }
        return BadRequest(ModelState);
    }

    public class NewSiteInformation {
        [Required]
        public string Alias { get; set; }
        [Required]
        public string DisplayName { get; set; }
        public string Description { get; set; }
        //...
    }
}

Note the inclusion of a proper strongly typed object model for the POST action, model validation and the returning of the proper HTTP status code as expected by the client. (204)

On the client side, update the URL being called to match the API controller’s route and update the options to send the correct content type.

//...

const options = {
  method: 'POST',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(
    {
        Alias: this.state.Alias,
        DisplayName: this.state.DisplayName, 
        Description: this.state.Description
    })      
};

adalApiFetch(fetch, "api/SiteCollections", options)
  .then(response =>{
    if(response.status === 204){
        Notification(
            'success',
            'Site collection created',
            ''
            );
     }else{
        throw "error";
     }
  })
  .catch(error => {
    Notification(
        'error',
        'Site collection not created',
        error
        );
    console.error(error);
});

//...

Note how the headers are directly in the fetch options as apposed to config.headers in the original code.

I have trouble with an error. Localhost works fine.But when it is in live server and makes a post request its show me 405 status code.

Laravel api route is :

Route::post('/add_mase/', 'Abc@add_mase');

And Laravel Method is

    public function add_mase(Request $r){
        $w = $this->d();

        if($data = DB::table('mess')->where('code', $r->code)->first()){
            $boder = $this->boder();
            DB::table('add_requ')->insert(['mId' => $data->id, 'bId' => $boder->id, 'dateTime' => date('d-m-Y h:i:s a') ]);
            return response( ['msg' => 'You Request Success. Your Mase Name is '.$data->name  , 'status' => false]);
        }

        return response( ['msg' => 'You Request not Success. Try exact Code', 'status' => true ]);  

    }

Now React Code are

JS6 react Form

import React from 'react';
import { connect } from 'react-redux';
import Header from "../Auth/Header";
import Footer from "../Auth/Footer";
import { withRouter } from 'react-router-dom';
import { checkMass, addMase } from '../../services/actions/BoderAction'



class AddMase extends React.Component {
  state = {
    code: '',
    form: true
  }

  onChangemorning = (e) => {
    this.setState({ code: e.target.value })
  }
  onSubmit = (e) => {
    e.preventDefault();

    const obj = {
      code: this.state.code,
    }
    this.props.addMase(obj)
  }

  componentDidMount() {
    this.props.checkMass(JSON.parse(localStorage.getItem('user')).id)
  }

  render() {

    if (this.props.loader == true) {
      return <div className="loader"></div>;
    }

    return (
      <>
        <Header />

        <div className="card o-hidden border-0 shadow-lg my-5">
          <div className="card-body p-0">
            <div className="row">
              <div className="col-lg-12">
                <div className="p-5">
                  <div className="text-center">

                    {this.props.sucMsg}

                    {this.props.form == true &&
                      <form method="POST" onSubmit={this.onSubmit} >
                        <div className="form-group">
                          <label htmlFor="exampleFormControlSelect1">Mase Code</label>
                          <input
                            type='text'
                            className="form-control"
                            onChange={this.onChangemorning}
                          />
                        </div>
                        <button type="submit" className="btn btn-primary">Request </button>
                      </form>
                    }


                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
        <Footer />
      </>
    );
  }
}
const mapStateToProps = (state) => {
  return {
    loader: state.boder.loading,
    errMsg: state.boder.errMsg,
    sucMsg: state.boder.sucMsg,
    form: state.boder.form,


  }
}


export default withRouter(connect(mapStateToProps, { checkMass, addMase })(AddMase));

Border Action for redux

export const addMase = (id) => async dispatch =>  {
    dispatch({type: LOADING})
    await axios.post(`${URL}/add_mase/`,  id, { 
        headers: {
          'Authorization' : localStorage.getItem("token")
        } 
      })
    .then( res => {
        console.log( res )
         dispatch({
            type: ADD_MASE,
            payload: {
                massage : res.data.msg,
                status : res.data.status
            }
        })
    })
    .catch(err => {
        dispatch({
            type: FAILED,
            payload: err.response.data.error
        })
    })
}

Boder Reducer

        case ADD_MASE:
            return { ...state, loading: false, sucMsg: payload.massage, form: payload.status }

those make a error status code 405

Browser console

GET https://example.com/admin/api/add_mase 405

N.B ssl not set to my domain

And Browser Network preview

The GET method is not supported for this route. Supported methods: POST

One more thing, localhost working fine in all routes. But in live server all post request creates 405 error. Get request works fine in live server too.

The following request is giving me a 405 Method not allowed when running from a simple create-react-app generated project from localhost:3000. I really need this app to run outside of the domain (decoupled). This feels very much like a cross origin issue but I’m sending the X-CSRF-TOKEN header token and have apache configured to accept the headers as well.

No idea what I’m doing wrong…

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

However, running the same code from within a custom module on the same domain executes as expected.

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;


UPDATE:

Here’s what my services.yml cors.config looked like: (THIS IS WRONG???)

   # 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

This is what my cors.config needs to be for it to work!!

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

Here’s what my apache.conf looks like:

<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>

NOT WORKING FROM A SEPARATE JS REACT APP

The following screenshot shows the result of running the same JS from within the contenta.loc domain (same server as the endpoint)

Drupal Custom Module Implementation

WORKING FROM WITHIN A CUSTOM MODULE

The following screenshot shows the error when running the JS from within the create-react-app nodejs localhost server.

405 (Method Not Allowed)

I am trying to connect my react-apollo client to my graphql backend and I keep getting a 405 error. My server is hosted on localhost port 3000, and my client is also on localhost (port 8100). I have enabled CORS in express to allow this conenction, but when my client tries to connect, I get the error:

OPTIONS http://localhost:3000/graphql 405 (Method Not Allowed)

Here are the request and response headers copied from my browser’s failed request:

General

Request URL:http://localhost:3000/graphql
Request Method:OPTIONS
Status Code:405 Method Not Allowed
Remote Address:[::1]:3000

Response Headers

Access-Control-Allow-Headers:Origin, X-Requested-With, Content-Type, Accept, Accept-Encoding, Accept-Language, Access-Control-Request-Headers, Access-Control-Request-Method
Access-Control-Allow-Methods:POST, GET, OPTIONS
Access-Control-Allow-Origin:*
Allow:POST
Connection:keep-alive
Date:Sun, 15 Jan 2017 20:21:41 GMT
Transfer-Encoding:chunked
X-Powered-By:Express

Request Headers

Accept:*/*
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:en-US,en;q=0.8,fr;q=0.6
Access-Control-Request-Headers:content-type
Access-Control-Request-Method:POST
Connection:keep-alive
DNT:1
Host:localhost:3000
Origin:http://localhost:8100
Referer:http://localhost:8100/
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36

And here is my server script file:

var express = require('express');
var bodyParser = require('body-parser');
var { graphqlExpress } = require('graphql-server-express');
var Schema = require('./server/schema.js');

const PORT = 3000;

var app = express();

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Accept-Encoding, Accept-Language, Access-Control-Request-Headers, Access-Control-Request-Method");
  next();
});

app.use('/graphql', bodyParser.json(), graphqlExpress({ schema: Schema }));

app.listen(PORT);

console.log('GraphQL Sandbox started on port: 3000');

react — returned by the backend 405

the reason: Background interface is a PUT method
I wrote POST

solve

export async function statusTeacher(params = {}) {
  return request(`server/xx/xx/xx?${stringify(params)}`, {
    method: 'PUT',
    // body: params
  });
}

Intelligent Recommendation

Nginx+React Ant Design 405 error

Why is it possible to configure a proxy locally, but not on nginx? Probably because there are proxies made by other servers locally, such as node, so nginx also needs to be configured The package is p…

More Recommendation

405

problem causes @PostMapping way problem solved Use postman conduct post test. Bug reproduce…

A way for React to interact with the backend

Last week, I needed to link a react front-end project with the spring back-end project. However, I have never done this kind of separation system before and after. Although I have learned the basics o…

React backend pagination

Under the api is the secondary package of axios index.js request.js Create a list component: Effect picture PS: Cross-domain issues mentioned The back end is node, port 4000, configuration proxy, fron…

Понравилась статья? Поделить с друзьями:
  • 405 ошибка laravel
  • 405 ошибка http сервис 1с
  • 405 ошибка html
  • 405 ошибка asp net core
  • 404в код ошибки яндекс