API Call From Word Web Add-In (Office.Js) Is Not Working: CORS Issue?
Asked Answered
M

3

6

Friends,

I am trying to call API from Word Add-in and getting "Access Denied" error. I did some research and it looks like "Cross Origin Resource Sharing" is the cause.

1. Web API

I am hosting Web API 2 locally at "http://localhost:61546/api/ORG_NAMES" & I have enabled CORS to accept all origins, See below WebApiConfig.

public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services
            var cors = new EnableCorsAttribute("*", "*", "*");
            config.EnableCors(cors);

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }

2. Test Application

To test this API to ensure it supports CORS, I have created below page and hosted on localhost:52799/home.html, I was able to get expected response. I have tested this in IE 10 & Chrome.

<!DOCTYPE html>
<html>
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script>
    $(document).ready(function(){
        $("button").click(function () {
            var obj;
            .support.cors = true;
            $.getJSON("http://localhost:61546/api/ORG_NAMES/112233",
                function (data) {
                alert(data.ORG_ID);
            });
        });
    });
    </script>
</head> 
<body>
    <button>Click me</button>
</body>

3. Word Add-In

Now I wanted to call this API from my Word Web Add-In. Word Add-In running from different host https://localhost:44339/, see below code. Here getJSON returns "Access Denied".

      var OrgID; 
      $.getJSON("http://localhost:61546/api/ORG_NAMES/112233",
             function (data) {
                 OrgID = data.ORG_ID;
             });

Also when I call API from word add-in, it's not going to fiddler.

Note: This is "Web Add-ins --> Word Add-in" project.

4. Fix - Need Help

Not sure why I am getting "Access Denied" error from Word-Add-In, if CORS is the issue then my test application (#2) shouldn't have worked, correct ?

I have tried call JSON using "$.ajax", "XMLHttpRequest" but it didn't work.I might be missing some configuration settings.

Appreciate any help here. Let me know if you need more information.

Maggard answered 1/8, 2016 at 20:37 Comment(3)
I had the same issues, I changed the app domains to the appropriate values, and also you have to make sure you are using https, because if you are using http you will get that CORs error. Make sure that when you launch your word add-in that you are httpsAverment
Hi anonymous friend - so are you saying that if you attempt a CORS request via Office-JS, and your api endpoint isn't SSL, Office JS JavaScript will reject it outright? - That is in fact what I am experiencing, but I can't find any documentation saying that's the case.Supposing
True. But every sample and page uses https, for example, see Addressing same-origin policy limitations in Office Add-insCitral
S
2

Since it sounds like an issue within an Office Add-in only, rather than in a regular page, have you tried setting your AppDomains in the manifest file? See "Specify domains you want to open in the add-in window" in https://dev.office.com/docs/add-ins/overview/add-in-manifests

<?xml version="1.0" encoding="UTF-8"?>
<OfficeApp xmlns="http://schemas.microsoft.com/office/appforoffice/1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="TaskPaneApp">
<Id>c6890c26-5bbb-40ed-a321-37f07909a2f0</Id>
<Version>1.0</Version>
<ProviderName>Contoso, Ltd</ProviderName>
<DefaultLocale>en-US</DefaultLocale>
<DisplayName DefaultValue="Northwind Traders Excel" />
<Description DefaultValue="Search Northwind Traders data from Excel"/>
<AppDomains>
    <AppDomain>https://www.northwindtraders.com</AppDomain>
</AppDomains>
<DefaultSettings>
    <SourceLocation DefaultValue="https://www.contoso.com/search_app/Default.aspx" />
</DefaultSettings>
<Permissions>ReadWriteDocument</Permissions>
</OfficeApp>
Saleme answered 1/8, 2016 at 23:43 Comment(3)
I have set the correct domain names, still its not working. Now I am trying with "JSONP" but looks like it also have some issues.Maggard
Going JSONP route can be limiting... If you're not able to get your site on one domain to talk to a server on another, you can always have a WebAPI in the same domain that proxies the request. See blogs.msdn.microsoft.com/officeapps/2013/06/10/… for more info.Saleme
Link is dead. New link: learn.microsoft.com/en-us/office/dev/add-ins/develop/…Nibbs
A
2

You will not need Jsonp if you are making Ajax calls. You will have to make sure that you all launches with HTTPS, if it is launching in HTTP it will block that traffic. Remember that office-js back bone is IE and there for; for security purposes the api will only allow HTTPS

Update

Remember that an office-js add in is actually two projects and you must make sure your projects are both launching in HTTPS. Also I would just look over the Manifest file and look at your source and make sure that is point at HTTPS

Averment answered 5/8, 2016 at 4:5 Comment(0)
C
0

I had same issue using ajax could not call web-api.NET MVC.

Web api side(Server side):

  1. Implement CORS in Web api because excel office.js works on diffent port and binds proxy object of server inside excel while web api are held on another port so it is as good as having 2 different domains on local so browser automatically blocks request made.

So Cross origin Resource sharing is required.

  1. Enable Https for web apis. http://csharp-video-tutorials.blogspot.com/2016/09/aspnet-web-api-enable-https.html

Client side

  1. Just make call using ajax as shown below. url: 'https://localhost:44319/api/Default/PostItems' Note : https : is compulsory required .

    function makeAjaxCall(rangeJSON) {
    
    $.ajax({
        url: 'https://localhost:44319/api/Default/PostItems',
        type: 'POST',
        data: rangeJSON,
        contentType: 'application/json;charset=utf-8',
    }).done(function (data) {
        console.log(data)
      app.showNotification(data.Status, data.Message);
    }).fail(function (status) {
       app.showNotification('Error', 'Could not communicate with the server.');
        }).always(showResponse);
    
    }
    
    
    function exceltojson() {
    Excel.run(function (ctx) {
    
        var range = ctx.workbook.worksheets.getItem("Sheet1").getRange("A1:BO765");
    
        range.load("values, numberFormat");
    
        ctx.sync().then(
            function () {
    
               makeAjaxCall(JSON.stringify(range.values));
    
            }).catch(function (error) {
                console.log(error);
    
            });
    });
    
    
    function showResponse(object) {
    
        console.log(object);
        $("#output").text(JSON.stringify(object,null, 4));
    }
    
Coelacanth answered 24/7, 2018 at 17:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.