【问题标题】:CORS No 'Access-Control-Allow-Origin' error in React app w/ FacebookCORS 在带有 Facebook 的 React 应用程序中没有“Access-Control-Allow-Origin”错误
【发布时间】:2021-10-25 19:26:01
【问题描述】:

我是一名初级开发人员,刚开始使用 Facebook for Developers。我正在使用我正在构建的 ReactJs 应用程序碰壁,可以使用您的帮助!

我的老板要求页面插件的网格表示,而不是实际的插件本身。对于这个项目,他要求我制作并使用一个测试“页面”文档。我知道它至少在我的 console.log 中达到了我想要的区域,因为它正在返回错误消息。

以下是我的浏览器返回的错误:

Access to fetch at 'https://www.facebook.com/Feeds-Tester-170107151801959/' from origin 'https://localhost:3000' 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.

GET https://www.facebook.com/Feeds-Tester-170107151801959/ net::ERR_FAILED

您将在我的 URL 变量中看到的链接已经过三重检查以确保链接正确。由于我使用的是 NodeJS,因此我尝试安装 CORS npm 包,但我不能 100% 确定在哪里使用它,我想知道这是否是问题的原因?

这是我的完整代码 sn-p(如果有帮助,我正在使用 VS Code):

/*global FB*/
import React from 'react';
import { DataGrid, Editing, Scrolling, Lookup, Summary, TotalItem } from 'devextreme-react/data-grid';
import { Button } from 'devextreme-react/button';
import { SelectBox } from 'devextreme-react/select-box';
import CustomStore from 'devextreme/data/custom_store';
import { formatDate } from 'devextreme/localization';
import 'whatwg-fetch';

const URL = 'https://www.facebook.com/Feeds-Tester-170107151801959/';
const REFRESH_MODES = ['full', 'reshape', 'repaint'];
class Grid extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      fbData: null,
      ordersData: new CustomStore({
        key: 'OrderID',
        load: () => this.sendRequest(`${URL}`, 'GET'),
      }),
      requests: [],
      refreshMode: 'reshape'
    };
    this.clearRequests = this.clearRequests.bind(this);
    this.handleRefreshModeChange = this.handleRefreshModeChange.bind(this);

  var body = 'Reading JS SDK documentation';
  FB.api('/me/feed', 'post', { message: body }, function(response) {
    if (!response || response.error) {
      console.log('Error occured');
    } else {
      console.log('Post ID: ' + response.id);
    }
  })
}

  sendRequest(url, method, data) {
    method = method || 'GET';
    data = data || {};
    this.logRequest(method, url, data);
    if(method === 'GET') {
      return fetch(url, {
        method: method,
        credentials: 'include',
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
          'Access-Control-Allow-Origin': '*'
        }
      }).then(result => result.json().then(json => {
        if(result.ok) return json.data;
        throw json.Message;
      }));
    }

    const params = Object.keys(data).map((key) => {
      return `${encodeURIComponent(key) }=${ encodeURIComponent(data[key])}`;
    }).join('&');
    return fetch(url, {
      method: method,
      body: params,
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
      },
      credentials: 'include'
    }).then(result => {
      if(result.ok) {
        return result.text().then(text => text && JSON.parse(text));
      } else {
        return result.json().then(json => {
          throw json.Message;
        });
      }
    });
  }

  logRequest(method, url, data) {
    const args = Object.keys(data || {}).map(function(key) {
      return `${key }=${ data[key]}`;
    }).join(' ');

    const time = formatDate(new Date(), 'HH:mm:ss');
    const request = [time, method, url.slice(URL.length), args].join(' ');
    this.setState((state) => {
      return { requests: [request].concat(state.requests) };
    });
  }
  clearRequests() {
    this.setState({ requests: [] });
  }
  handleRefreshModeChange(e) {
    this.setState({ refreshMode: e.value });
  }
  render() {
    const { refreshMode, ordersData } = this.state;
    return (
      <React.Fragment>
        <DataGrid
          id="grid"
          showBorders={true}
          dataSource={ordersData}
          repaintChangesOnly={true}
        >
          <Editing
            refreshMode={refreshMode}
            mode="cell"
            allowAdding={true}
            allowDeleting={true}
            allowUpdating={true}
          />

          <Scrolling
            mode="virtual"
          />

          <Lookup dataSource={ordersData} valueExpr="Value" displayExpr="Text" />

          <Summary>
            {/* <TotalItem column="CustomerID" summaryType="count" />
            <TotalItem column="Freight" summaryType="sum" valueFormat="#0.00" /> */}
          </Summary>

        </DataGrid>
        <div className="options">
          <div className="caption">Options</div>
          <div className="option">
            <span>Refresh Mode: </span>
            <SelectBox
              value={refreshMode}
              items={REFRESH_MODES}
              onValueChanged={this.handleRefreshModeChange}
            />
          </div>
          <div id="requests">
            <div>
              <div className="caption">Network Requests</div>
              <Button id="clear" text="Clear" onClick={this.clearRequests} />
            </div>
            <ul>
              {this.state.requests.map((request, index) => <li key={index}>{request}</li>)}
            </ul>
          </div>
        </div>
      </React.Fragment>
    );
  }
}

export default Grid;

This is the link to the docs for the module I'm trying to reference

我尽量不吃太多,我什至在考虑操作数据或发送任何回报之前就开始检索数据。您可以提供的任何见解或指导将不胜感激。谢谢!! :)

【问题讨论】:

  • 您无法从客户端浏览器获取 Facebook,您需要在任何地方使用自托管的 cors,或者在您自己的 API 中进行操作
  • @iunfixit 谢谢你的链接!所以你是说将带有FB.api 的部分移动到我的API 并在那里而不是在客户端运行该调用,只是为了确认?
  • 不不,获取不与 Facebook URL 一起使用,您可以使用 API(FB.api) 代替,它会起作用,将 fetch 替换为 FB.api 调用,我会发送答案
  • 如果答案需要更多代码,我可以编辑它,基本上 sendRequest 需要使用 FB.api 而不是 fetch,如果您打算将它用于 Facebook URL

标签: javascript reactjs facebook cors devexpress


【解决方案1】:

不要将 fetch 与 Facebook URL 一起使用,它不会让它发生在浏览器上,而是使用 Facebook API 来完成您需要使用它做的所有事情

例如,不获取页面,而是将 api 与页面一起使用

FB.api('/Feeds-Tester-170107151801959', function(response) {
  // ...
});

如果您需要获取页面,那么您必须在浏览器环境之外进行,或者在任何地方使用类似 cors 的代理,但您可以通过使用 Facebook API 来避免这种情况

【讨论】:

  • 谢谢! :) 我刚刚运行了您发送的 sn-p 并添加了 console.log(response),这次我似乎走得更远了,但现在我遇到了一个我也不完全理解的错误:{error: {…}} error: code: 100 error_subcode: 33 fbtrace_id: "A_RiTZEZ3dsCllkn9GSsOUx" message: "Unsupported get request. Object with ID 'Feeds-Tester-170107151801959' does not exist, cannot be loaded due to missing permissions, or does not support this operation. Please read the Graph API documentation at https://developers.facebook.com/docs/graph-api" type: "GraphMethodException"
  • 这是否暗示它与页面上的隐私/权限有关?
  • 它可能有错误的 ID,我不确定它是否仅适用于 /Feeds-Tester-170107151801959,尝试 /170107151801959 或在页面上查看 facebook.com/help/1503421039731588
  • 啊,是的,非常感谢!跟踪正确的 ID,它能够毫无问题地返回 console.log :) 现在我只需要弄清楚如何实际呈现帖子本身......再次感谢您!
猜你喜欢
  • 2017-09-02
  • 2021-05-06
  • 1970-01-01
  • 1970-01-01
  • 2018-02-02
  • 2017-12-06
  • 2021-01-13
  • 2018-08-30
  • 2016-01-11
相关资源
最近更新 更多