简体   繁体   English

API 和 UI 之间的访问错误(react JS)

[英]Access error between API and UI (react JS)

I created UI part in JS using React (It's my first experience - here could be errors).我使用 React 在 JS 中创建了 UI 部分(这是我的第一次体验 - 这可能是错误的)。 Also I created Backend part - it works good, I tested it.我还创建了后端部分 - 它运行良好,我对其进行了测试。 When I tried unite it - I get this error.当我尝试联合它时 - 我收到此错误。 I have a problem with access -> when user click on a submit button (I get this error)我有访问问题 ->当用户单击提交按钮时(我收到此错误) 在此处输入图片说明

Could you explain what I did wrong.你能解释一下我做错了什么吗? I think my UI part is good, I think problem in an API part.我认为我的 UI 部分很好,我认为 API 部分存在问题。 I attached both: UI (react JS) :我附上了两个: UI(反应JS)

import React from 'react';
import { Link } from 'react-router-dom';
import { notification, Alert, Spin, Form, Input, Button, Typography } from 'antd';
import { usePromise } from 'innroad.common.ui';
import * as apiService from 'services/ApiService';
import { LAYOUT, TAIL_LAYOUT } from 'constants/layouts';
import styles from './AddTownCreation.scss';

const AddTownCreation = () => {
  const onFail = () => notification.error({ message: 'some error occured while creating template' });

  const [{ data, isLoading }, createNewTown] = usePromise(apiService.createTown, { initialData: [], onFail });

  const handleFormFinish = (formValue) => createNewTown(formValue);

  return (
    <>
      <Spin spinning={isLoading}>
        <Typography.Title>Create New Town</Typography.Title>
        {data.length > 0 && (<Alert message={`New town id : ${data.join(',')}`} type="info" />)}
        <Form {...LAYOUT} onFinish={handleFormFinish}>
          <Form.Item
            name="name"
            label="Town Name :"
            rules={[{ whitespace: true, required: true, message: 'This is required field' }]}
          >
            <Input />
          </Form.Item>
          <Form.Item {...TAIL_LAYOUT}>
            <Button htmlType="submit" className={styles.rightMargin}>Submit</Button>
            <Button type="link" className="ant-btn"><Link to="/">Cancel</Link></Button>
          </Form.Item>
        </Form>
      </Spin>
    </>
  );
};

export default AddTownCreation;

API in JS : JS 中的 API

import { get, post } from './HttpService';

/**
 * ---------------------------------
 * endpoints
 * ---------------------------------
 */

export const createTown = async (data) => post('/add.town', data);

API that I created in C#我在 C# 中创建的 API

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using innRoad.innSupportTools.Services;
using innRoad.innSupportTools.ViewModels;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

{
    [Route("api")]
    [ApiController]
    public class TownController : ControllerBase
    {
        public readonly ITownService _townService;

        public TownController(ITownService townService)
        {
            _townService = townService;
        }

        [HttpPost]
        [Route("add.town")]
        public async Task<int> InsertTown([FromBody] TownViewModel town)
        {
            return await _townService.InsertTown(town.Name);
        }

        [HttpGet]
        [Route("GetTown/{townId}")]
        public async Task<TownViewModel> GetTown(int townId)
        {
            return await _townService.GetTown(townId);
        }
    }
}

TownViewModel城市景观模型

{
    public class TownViewModel
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
}

Backend part works good后端部分运行良好

尝试在控制器顶部添加 [EnableCors("AllowAll")]

Browsers are implemented with same-origin policy - this means that any request across domain boundaries (different origin) are blocked by default.浏览器采用同源策略实现 - 这意味着默认情况下会阻止跨域边界(不同来源)的任何请求。 But this is a common use case - that you want to get a public resource from a different origin.但这是一个常见用例 - 您想要从不同来源获取公共资源。 For example, you will need to get data from a third party provider.例如,您需要从第三方提供商处获取数据。

To make this work, the server that provides data needs let the browser know that "the origin where the request is coming from can access my resource/data".为了完成这项工作,提供数据的服务器需要让浏览器知道“请求来自的源可以访问我的资源/数据”。 The browser remembers that and allows cross-origin resource sharing.浏览器记住这一点并允许跨源资源共享。

Step 1: Browser第 1 步:浏览器

When the browser is making a cross-origin request, the browser adds an Origin header with the current origin (scheme, host, and port).当浏览器发出跨域请求时,浏览器会添加一个带有当前源(方案、主机和端口)的 Origin 标头。

Step 2: server第二步:服务器

On the server side, when a server sees this header, and wants to allow access, it needs to add an Access-Control-Allow-Origin header to the response specifying the requesting origin (or * to allow any origin.)在服务器端,当服务器看到这个标头并想要允许访问时,它需要在响应中添加一个 Access-Control-Allow-Origin 标头,指定请求的来源(或 * 以允许任何来源。)

Step 3: browser receives response第三步:浏览器接收响应

When the browser sees this response with an appropriate Access-Control-Allow-Origin header, the browser allows the response data to be shared with the client site.当浏览器看到带有适当 Access-Control-Allow-Origin 标头的响应时,浏览器允许与客户端站点共享响应数据。

So if you want to take the application to production then what you need to implement is step 2, check the origin header for the requests if it is from a valid whitelisted URL (like your UI application url) then set the Access-Control-Allow-Origin header.因此,如果您想将应用程序投入生产,那么您需要实现的是第 2 步,检查请求的原始标头是否来自有效的白名单 URL(如您的 UI 应用程序 URL),然后设置 Access-Control-Allow - 原标题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM