'http://localhost:8000' has been blocked by CORS policy

I’m working on the Pro MERN Stack: Full Stack Web App Development with Mongo, Express, React, and Node book, and I ran into CORS policy errors whenever I tried to go back to my homepage. It looks like the error is coming from my graphqlFetch file but I’m not so sure what the issue is. Any insight would be extremely helpful!!

CORS policy error message

enter image description here

GraphQLFetch error enter image description here 1: My GraphQLFetch code:

import fetch from 'isomorphic-fetch';  const dateRegex = new RegExp('^\\d\\d\\d\\d-\\d\\d-\\d\\d');  function jsonDateReviver(key, value) {   if (dateRegex.test(value)) return new Date(value);   return value; }  export default async function graphQLFetch(query, variables = {}, showError = null, cookie = null) {   const apiEndpoint = (__isBrowser__) // eslint-disable-line no-undef     ? window.ENV.UI_API_ENDPOINT     : process.env.UI_SERVER_API_ENDPOINT;   try {     const headers = { 'Content-Type': 'application/json' };     if (cookie) headers.Cookie = cookie;     const response = await fetch(apiEndpoint, {       method: 'POST',       credentials: 'include',       headers,       body: JSON.stringify({ query, variables }),     });     const body = await response.text();     const result = JSON.parse(body, jsonDateReviver);      if (result.errors) {       const error = result.errors[0];       if (error.extensions.code === 'BAD_USER_INPUT') {         const details = error.extensions.exception.errors.join('\n ');         if (showError) showError(`${error.message}:\n ${details}`);       } else if (showError) {         showError(`${error.extensions.code}: ${error.message}`);       }     }     return result.data;   } catch (e) {     if (showError) showError(`Error in sending data to server: ${e.message}`);     return null;   } }

My IssueEdit file

import React from 'react'; import { Link } from 'react-router-dom'; import { LinkContainer } from 'react-router-bootstrap'; import {   Col, Panel, Form, FormGroup, FormControl, ControlLabel,   ButtonToolbar, Button, Alert, } from 'react-bootstrap';  import graphQLFetch from './graphQLFetch.js'; import NumInput from './NumInput.jsx'; import DateInput from './DateInput.jsx'; import TextInput from './TextInput.jsx'; import Toast from './Toast.jsx'; import store from './store.js';  export default class IssueEdit extends React.Component {   static async fetchData(match, search, showError) {     const query = `query issue($id: Int!) {       issue(id: $id) {         id title status owner         effort created due description       }     }`;      const { params: { id } } = match;     const result = await graphQLFetch(query, { id }, showError);     return result;   }    constructor() {     super();     const issue = store.initialData ? store.initialData.issue : null;     delete store.initialData;     this.state = {       issue,       invalidFields: {},       showingValidation: false,       toastVisible: false,       toastMessage: '',       toastType: 'success',     };     this.onChange = this.onChange.bind(this);     this.handleSubmit = this.handleSubmit.bind(this);     this.onValidityChange = this.onValidityChange.bind(this);     this.dismissValidation = this.dismissValidation.bind(this);     this.showValidation = this.showValidation.bind(this);     this.showSuccess = this.showSuccess.bind(this);     this.showError = this.showError.bind(this);     this.dismissToast = this.dismissToast.bind(this);   }    componentDidMount() {     const { issue } = this.state;     if (issue == null) this.loadData();   }    componentDidUpdate(prevProps) {     const { match: { params: { id: prevId } } } = prevProps;     const { match: { params: { id } } } = this.props;     if (id !== prevId) {       this.loadData();     }   }    onChange(event, naturalValue) {     const { name, value: textValue } = event.target;     const value = naturalValue === undefined ? textValue : naturalValue;     this.setState(prevState => ({       issue: { ...prevState.issue, [name]: value },     }));   }    onValidityChange(event, valid) {     const { name } = event.target;     this.setState((prevState) => {       const invalidFields = { ...prevState.invalidFields, [name]: !valid };       if (valid) delete invalidFields[name];       return { invalidFields };     });   }    async handleSubmit(e) {     e.preventDefault();     this.showValidation();     const { issue, invalidFields } = this.state;     if (Object.keys(invalidFields).length !== 0) return;      const query = `mutation issueUpdate(       $id: Int!       $changes: IssueUpdateInputs!     ) {       issueUpdate(         id: $id         changes: $changes       ) {         id title status owner         effort created due description       }     }`;      const { id, created, ...changes } = issue;     const data = await graphQLFetch(query, { changes, id }, this.showError);     if (data) {       this.setState({ issue: data.issueUpdate });       this.showSuccess('Updated issue successfully');     }   }    async loadData() {     const { match } = this.props;     const data = await IssueEdit.fetchData(match, null, this.showError);     this.setState({ issue: data ? data.issue : {}, invalidFields: {} });   }    showValidation() {     this.setState({ showingValidation: true });   }    dismissValidation() {     this.setState({ showingValidation: false });   }    showSuccess(message) {     this.setState({       toastVisible: true, toastMessage: message, toastType: 'success',     });   }    showError(message) {     this.setState({       toastVisible: true, toastMessage: message, toastType: 'danger',     });   }    dismissToast() {     this.setState({ toastVisible: false });   }    render() {     const { issue } = this.state;     if (issue == null) return null;      const { issue: { id } } = this.state;     const { match: { params: { id: propsId } } } = this.props;     if (id == null) {       if (propsId != null) {         return <h3>{`Issue with ID ${propsId} not found.`}</h3>;       }       return null;     }      const { invalidFields, showingValidation } = this.state;     let validationMessage;     if (Object.keys(invalidFields).length !== 0 && showingValidation) {       validationMessage = (         <Alert bsStyle="danger" onDismiss={this.dismissValidation}>           Please correct invalid fields before submitting.         </Alert>       );     }      const { issue: { title, status } } = this.state;     const { issue: { owner, effort, description } } = this.state;     const { issue: { created, due } } = this.state;     const { toastVisible, toastMessage, toastType } = this.state;      return (       <Panel>         <Panel.Heading>           <Panel.Title>{`Editing issue: ${id}`}</Panel.Title>         </Panel.Heading>         <Panel.Body>           <Form horizontal onSubmit={this.handleSubmit}>             <FormGroup>               <Col componentClass={ControlLabel} sm={3}>Created</Col>               <Col sm={9}>                 <FormControl.Static>                   {created.toDateString()}                 </FormControl.Static>               </Col>             </FormGroup>             <FormGroup>               <Col componentClass={ControlLabel} sm={3}>Status</Col>               <Col sm={9}>                 <FormControl                   componentClass="select"                   name="status"                   value={status}                   onChange={this.onChange}                 >                   <option value="New">New</option>                   <option value="Assigned">Assigned</option>                   <option value="Fixed">Fixed</option>                   <option value="Closed">Closed</option>                 </FormControl>               </Col>             </FormGroup>             <FormGroup>               <Col componentClass={ControlLabel} sm={3}>Owner</Col>               <Col sm={9}>                 <FormControl                   componentClass={TextInput}                   name="owner"                   value={owner}                   onChange={this.onChange}                   key={id}                 />               </Col>             </FormGroup>             <FormGroup>               <Col componentClass={ControlLabel} sm={3}>Effort</Col>               <Col sm={9}>                 <FormControl                   componentClass={NumInput}                   name="effort"                   value={effort}                   onChange={this.onChange}                   key={id}                 />               </Col>             </FormGroup>             <FormGroup validationState={               invalidFields.due ? 'error' : null             }             >               <Col componentClass={ControlLabel} sm={3}>Due</Col>               <Col sm={9}>                 <FormControl                   componentClass={DateInput}                   onValidityChange={this.onValidityChange}                   name="due"                   value={due}                   onChange={this.onChange}                   key={id}                 />                 <FormControl.Feedback />               </Col>             </FormGroup>             <FormGroup>               <Col componentClass={ControlLabel} sm={3}>Title</Col>               <Col sm={9}>                 <FormControl                   componentClass={TextInput}                   size={50}                   name="title"                   value={title}                   onChange={this.onChange}                   key={id}                 />               </Col>             </FormGroup>             <FormGroup>               <Col componentClass={ControlLabel} sm={3}>Description</Col>               <Col sm={9}>                 <FormControl                   componentClass={TextInput}                   tag="textarea"                   rows={4}                   cols={50}                   name="description"                   value={description}                   onChange={this.onChange}                   key={id}                 />               </Col>             </FormGroup>             <FormGroup>               <Col smOffset={3} sm={6}>                 <ButtonToolbar>                   <Button bsStyle="primary" type="submit">Submit</Button>                   <LinkContainer to="/issues">                     <Button bsStyle="link">Back</Button>                   </LinkContainer>                 </ButtonToolbar>               </Col>             </FormGroup>             <FormGroup>               <Col smOffset={3} sm={9}>{validationMessage}</Col>             </FormGroup>           </Form>         </Panel.Body>         <Panel.Footer>           <Link to={`/edit/${id - 1}`}>Prev</Link>           {' | '}           <Link to={`/edit/${id + 1}`}>Next</Link>         </Panel.Footer>         <Toast           showing={toastVisible}           onDismiss={this.dismissToast}           bsStyle={toastType}         >           {toastMessage}         </Toast>       </Panel>     );   } }

My IssueList file:

import React from 'react'; import URLSearchParams from 'url-search-params'; import { Panel } from 'react-bootstrap';  import IssueFilter from './IssueFilter.jsx'; import IssueTable from './IssueTable.jsx'; import IssueDetail from './IssueDetail.jsx'; import graphQLFetch from './graphQLFetch.js'; import withToast from './withToast.jsx'; import store from './store.js';  class IssueList extends React.Component {   static async fetchData(match, search, showError) {     const params = new URLSearchParams(search);     const vars = { hasSelection: false, selectedId: 0 };     if (params.get('status')) vars.status = params.get('status');      const effortMin = parseInt(params.get('effortMin'), 10);     if (!Number.isNaN(effortMin)) vars.effortMin = effortMin;     const effortMax = parseInt(params.get('effortMax'), 10);     if (!Number.isNaN(effortMax)) vars.effortMax = effortMax;      const { params: { id } } = match;     const idInt = parseInt(id, 10);     if (!Number.isNaN(idInt)) {       vars.hasSelection = true;       vars.selectedId = idInt;     }      const query = `query issueList(       $status: StatusType       $effortMin: Int       $effortMax: Int       $hasSelection: Boolean!       $selectedId: Int!     ) {       issueList(         status: $status         effortMin: $effortMin         effortMax: $effortMax       ) {         id title status owner         created effort due       }       issue(id: $selectedId) @include (if : $hasSelection) {         id description       }     }`;      const data = await graphQLFetch(query, vars, showError);     return data;   }    constructor() {     super();     const issues = store.initialData ? store.initialData.issueList : null;     const selectedIssue = store.initialData       ? store.initialData.issue       : null;     delete store.initialData;     this.state = {       issues,       selectedIssue,      };     this.closeIssue = this.closeIssue.bind(this);     this.deleteIssue = this.deleteIssue.bind(this);   }    componentDidMount() {     const { issues } = this.state;     if (issues == null) this.loadData();   }    componentDidUpdate(prevProps) {     const {       location: { search: prevSearch },       match: { params: { id: prevId } },     } = prevProps;     const { location: { search }, match: { params: { id } } } = this.props;     if (prevSearch !== search || prevId !== id) {       this.loadData();     }   }    async loadData() {     const { location: { search }, match, showError } = this.props;     const data = await IssueList.fetchData(match, search, showError);     if (data) {       this.setState({ issues: data.issueList, selectedIssue: data.issue });     }   }    async closeIssue(index) {     const query = `mutation issueClose($id: Int!) {       issueUpdate(id: $id, changes: { status: Closed }) {         id title status owner         effort created due description       }     }`;     const { issues } = this.state;     const { showError } = this.props;     const data = await graphQLFetch(query, { id: issues[index].id },       showError);     if (data) {       this.setState((prevState) => {         const newList = [...prevState.issues];         newList[index] = data.issueUpdate;         return { issues: newList };       });     } else {       this.loadData();     }   }    async deleteIssue(index) {     const query = `mutation issueDelete($id: Int!) {       issueDelete(id: $id)     }`;     const { issues } = this.state;     const { location: { pathname, search }, history } = this.props;     const { id } = issues[index];     const { showSuccess, showError } = this.props;     const data = await graphQLFetch(query, { id }, showError);     if (data && data.issueDelete) {       this.setState((prevState) => {         const newList = [...prevState.issues];         if (pathname === `/issues/${id}`) {           history.push({ pathname: '/issues', search });         }         newList.splice(index, 1);         return { issues: newList };       });       showSuccess(`Deleted issue ${id} successfully.`);     } else {       this.loadData();     }   }     render() {     const { issues } = this.state;     if (issues == null) return null;       const { selectedIssue } = this.state;     return (       <React.Fragment>         <Panel>           <Panel.Heading>             <Panel.Title toggle>Filter</Panel.Title>           </Panel.Heading>           <Panel.Body collapsible>             <IssueFilter />           </Panel.Body>         </Panel>         <IssueTable           issues={issues}           closeIssue={this.closeIssue}           deleteIssue={this.deleteIssue}         />         <IssueDetail issue={selectedIssue} />        </React.Fragment>     );   } }  const IssueListWithToast = withToast(IssueList); IssueListWithToast.fetchData = IssueList.fetchData;  export default IssueListWithToast;

Add Comment
2 Answer(s)

Check if 127.0.0.1:8000 works instead of localhost:8000

Add Comment

You have to allow cross origin on your graphql server. For security reasons browsers didn’t allow ajax request on cross origin. So lets say you’re on localhost:3000 and your server is running on localhost:8000 so these two are on different origins.

So use cors module on Express server and allow Access-Control-Allow-Origin to "*"

Answered on July 16, 2020.
Add Comment

Your Answer

By posting your answer, you agree to the privacy policy and terms of service.