Webpack 开发服务器中 Twitter api 调用的 CORS 问题

Posted

技术标签:

【中文标题】Webpack 开发服务器中 Twitter api 调用的 CORS 问题【英文标题】:CORS issue with Twitter api calls in Webpack dev server 【发布时间】:2018-08-06 15:32:44 【问题描述】:

我在从 twitter api 获取响应时遇到了问题(使用 npm 包 Twitter)。在 Chrome 中我得到:

无法加载https://api.twitter.com/1.1/search/tweets.json?q=node.js:对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,Origin 'http://localhost:3000' 不允许访问。响应的 HTTP 状态代码为 400。如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。

所以我用插件启用了 CORS,错误变为:

无法加载 https://api.twitter.com/1.1/search/tweets.json?q=node.js:预检响应包含无效的 HTTP 状态代码 400。

我现在不知道该怎么做。我在 webpack.config.js 中尝试了一些不同的东西:

var path = require('path');
var webpack = require('webpack');
var Dotenv = require('dotenv-webpack');

module.exports = 
    devServer: 
        inline: true,
        historyApiFallback: true,
        contentBase: './src',
        port: 3000,
        headers: 
            "Access-Control-Allow-Origin": "*",
            "Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept",
            "Access-Control-Allow-Credentials": "true",
            "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS"
        ,
        proxy: 
            "/api": "http://localhost:3000"
        
    ,
    devtool: 'cheap-module-eval-source-map',
    entry: './dev/js/index.js',
    module: 
        loaders: [
            
                test: /\.js$/,
                loaders: ['babel'],
                exclude: /node_modules/
            ,
            
                test: /\.scss/,
                loader: 'style-loader!css-loader!sass-loader'
            ,
            
                loader: 'json-loader',
                test: /\.json$/ 
            
        ]
    ,
    output: 
        path: 'src',
        filename: 'js/bundle.min.js'
    ,
    node: 
        console: false,
        fs: 'empty',
        net: 'empty',
        tls: 'empty'
    ,
    plugins: [
        new webpack.optimize.OccurrenceOrderPlugin(),
        new Dotenv(
            path: './.env',
            safe: false
        )
    ]
;

这是我要打的电话

import Twitter from 'twitter';

const client = new Twitter(
  consumer_key: process.env.TWITTER_CONSUMER_KEY,
  consumer_secret: process.env.TWITTER_CONSUMER_SECRET,
  bearer_token: process.env.TWITTER_BEARER_TOKEN
);

client.get('search/tweets', q: 'node.js', function(error, tweets, response) 
   console.log(tweets);
);

我也在 firefox 中尝试过启用了 CORS 插件,但我得到了这个错误:

跨域请求被阻止:同源策略不允许读取位于https://api.twitter.com/1.1/search/tweets.json?q=node.js 的远程资源。 (原因:CORS 预检通道未成功)。

【问题讨论】:

【参考方案1】:

我只能想到一个解决方法:

使用 chrome 扩展 Allow-Control-Allow-Origin 使用代理:不要访问https://api.twitter.com/1.1/search/tweets.json?q=node.js,而是使用像https://cors-anywhere.herokuapp.com/这样的代理作为前缀:https://cors-anywhere.herokuapp.com/https://api.twitter.com/1.1/search/tweets.json?q=node.js

【讨论】:

嗯.. 我在 webpack 中做这个代理吗? proxy: "/api": "cors-anywhere.herokuapp.com" 我将它添加到我的 devServer 对象中,但它似乎没有任何区别 我不是 100% 确定,但我认为这不会起作用,因为像 cors-anywhere 这样的东西不允许身份验证标头 @GeraldWangley devServer.proxy 不是为这种情况而设计的。它旨在将对 webpack-dev-server 的请求代理到您配置的任何 url。由于Twitter 客户端直接请求api.twitter.com,您的devServer.proxy 不会有任何效果。只需尝试此处列出的@Rahamin,安装浏览器 CORS 扩展或使用外部 CORS 代理服务。【参考方案2】:

我是在 react 上做的。我遇到了同样的问题,为了解决这个问题,我在 node 中安装了一个 express 服务器,创建测试端点,需要 twitter 并按照 npm 站点上的步骤进行操作。然后我会在前端用一个 fetch 请求到达 express 端点,这反过来会从 twitter 收集数据,然后将来自 twitter 的响应发送回前端。

我在 localhost:4000 上运行 express 服务器,在 localhost:3000 上运行我的 create-react-app,然后我转到 package.json 以在 "scripts" : 上方添加 "proxy": "http://localhost:4000"(尽管在哪里并不重要)。

像魅力一样工作^_^

【讨论】:

示例代码总是很好。你能提供给我们吗?【参考方案3】:

您的浏览器在向您的 webpack 开发服务器代理发出 HTTP 请求时设置了一个原始标头,并且代理将此原始标头转发到 Twitter。 Twitter 很可能会根据其非法来源拒绝该请求。您可以通过在转发请求之前删除原始标头来解决此问题:

devServer: 
  ...,
  proxy: 
    ...,
    onProxyReq: function onProxyReq(proxyReq, req, res) 
      proxyReq.removeHeader("origin")
    
  

【讨论】:

以上是关于Webpack 开发服务器中 Twitter api 调用的 CORS 问题的主要内容,如果未能解决你的问题,请参考以下文章

HTTPS时,React截取/ auth / twitter /。我想从我的节点服务器访问/ auth / twitter /而不是反应应用程序

css Boostrap 3媒体查询 - https://scotch.io/quick-tips/default-sizes-for-twitter-bootstraps-media-querie

无法在nodejs中导入带有require()的模块

android 应用上的 twitter 集成

在 webpack 包中运行 Webpack 开发服务器

Vue.js 和 Webpack,如何构建组件以实现可移植性