【问题标题】:Office add-in: XMLHttpRequest cannot load XXX due to access control checksOffice 加载项:由于访问控制检查,XMLHttpRequest 无法加载 XXX
【发布时间】:2019-01-17 23:51:31
【问题描述】:

我正在使用 jQuery 和 Office JS API 构建 Outlook 加载项。我在开发时有一个本地服务器正在运行,我正在尝试向我的站点主服务器上的端点提交一个 POST 请求。每次我尝试提交请求时,都会收到以下三个错误:

Origin https://localhost:3000 is not allowed by Access-Control-Allow-Origin

XMLHttpRequest cannot load https://myurl.com/my_endpoint due to access control checks

Failed to load resource: Origin https://localhost:3000 is not allowed by Access-Control-Allow-Origin

到目前为止我做了什么:

找到这个相关的帖子:HTTP fetch from within Outlook add-ins

唯一的答案是做三件事:

  1. 使用 XMLHttpRequest 发出请求。是的,做到了:
function submitForm(var1, var2) {
    var http = new XMLHttpRequest();
    var params = 'var1=' + encodeURIComponent(var1) + '&var2=' + encodeURIComponent(var2);
    http.open("POST", 'https://myurl.com/my_endpoint', true);
    http.setRequestHeader('Access-Control-Allow-Origin', 'https://localhost:3000');
    http.setRequestHeader('Access-Control-Allow-Credentials', true);
    http.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 
    http.onreadystatechange = function() {
        console.log("response:", http.responseText);
        console.log("status:", http.status);
    };
    http.send(params);
}
  1. 将服务 URL 添加到清单的 AppDomains 列表中。是的,也这样做了。这是来自我的 manifest.xml:
<AppDomains>
    <AppDomain>https://myurl.com</AppDomain>
    <AppDomain>https://myurl.com/my_endpoint</AppDomain>
    <AppDomain>https://localhost:3000</AppDomain>
</AppDomains>
  1. 仅使用 SSL 连接下的服务。是的,myurl.com 服务器只能通过 SSL 访问。

我还找到了建议使用跨域资源共享 (CORS) 解决此问题的文档 (https://docs.microsoft.com/en-us/office/dev/add-ins/develop/addressing-same-origin-policy-limitations),并指向此链接:https://www.html5rocks.com/en/tutorials/file/xhr2/#toc-cors

所以,我检查了https://myurl.com 的服务器设置,实际上我允许来自任何来源的请求。更新 1:作为示例,下面是对https://myurl.com/my_endpoint 的成功网络请求的输出(注意Accept: */* 标头):

Request URL: https://myurl.com/my_endpoint
Request Method: POST
Status Code: 200 OK
Referrer Policy: no-referrer-when-downgrade
Cache-Control: no-cache, no-store, must-revalidate, public, max-age=0
Connection: keep-alive
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
Expires: 0
Pragma: no-cache
Server: nginx/1.10.3 (Ubuntu)
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Content-Length: 52
Content-type: application/x-www-form-urlencoded
Host: myurl.com
Origin: chrome-extension://focmnenmjhckllnenffcchbjdfpkbpie
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36
var1: var1
var2: var2

另外,让我相信问题不在于https://myurl.com 的另一件事是:当我在调试器中打开网络选项卡时,我可以看到我的请求永远不会到达https://myurl.com。我也没有在我的https://myurl.com 服务器日志中看到请求 ping。这是我尝试从 Outlook 加载项 ping https://myurl.com 时网络请求的输出:

Summary
URL: https://myurl.com/my_endpoint
Status: —
Source: —

Request
Access-Control-Allow-Origin: https://localhost:3000
Access-Control-Allow-Credentials: true
Content-Type: application/x-www-form-urlencoded
Origin: https://localhost:3000
Accept: */*
Referer: https://localhost:3000/index.html?_host_Info=Outlook$Mac$16.02$en-US
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14) AppleWebKit/605.1.15 (KHTML, like Gecko)

Response
No response headers

Request Data
MIME Type: application/x-www-form-urlencoded
var1: var1
var2: var2

对于我还需要更改哪些内容才能向 myurl.com 发出 POST 请求有什么建议吗?提前感谢帮助我解决这个问题的好心人。

更新 2:就其价值而言,除了运行 npm install -g generator-office 时开箱即用的配置之外,我还没有对节点服务器进行任何配置。例如。这两个文件我没碰过:

.babelrc

{
    "presets": [
        "env"
    ]
}

webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: {
        polyfill: 'babel-polyfill',
        app: './src/index.js',
        'function-file': './function-file/function-file.js'
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: 'babel-loader'
            },
            {
                test: /\.html$/,
                exclude: /node_modules/,
                use: 'html-loader'
            },
            {
                test: /\.(png|jpg|jpeg|gif)$/,
                use: 'file-loader'
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './index.html',
            chunks: ['polyfill', 'app']
        }),
        new HtmlWebpackPlugin({
            template: './function-file/function-file.html',
            filename: 'function-file/function-file.html',
            chunks: ['function-file']
        })
    ]
};

【问题讨论】:

  • 看起来你正在使用 node.js。您能否分享一下您如何配置 CORS 以接受来自任何 url 的请求?
  • 我在本地运行节点服务器以在开发时托管我的加载项。我确实认为问题出在本地,而不是在 Azure 上托管的带有 Python 后端的 myurl.com 服务器的设置中,但仅供参考,我已将成功 ping 到 myurl.com/my_endpoint 的网络输出包含在上面的问题

标签: xmlhttprequest office365 office-js outlook-web-addins javascript-api-for-office


【解决方案1】:

加载资源失败:Access-Control-Allow-Origin 不允许 Origin https://localhost:3000

服务器响应您的pre-flight 请求(通常是OPTIONS)并且不允许获得响应,这是因为您的来源localhost:3000 在服务器端是不允许的。

您需要在服务器上使用204 status 代码和如下标题响应OPTIONS

Access-Control-Allow-Origin 'localhost';

【讨论】:

  • 您好,感谢您抽出宝贵时间提供帮助。请参见上文 - 我已经在我的请求标头中指定了 Access-Control-Allow-Origin: https://localhost:3000。除了我已经完成的工作之外,我的代码中是否还有其他地方需要指定?
  • @tswift 这个标头是从服务器端而不是从客户端设置的。
猜你喜欢
  • 1970-01-01
  • 2018-05-29
  • 2018-11-12
  • 2020-10-28
  • 2020-12-18
  • 1970-01-01
  • 2020-10-18
  • 2017-09-16
  • 2018-03-07
相关资源
最近更新 更多