Outlook Add-in: How to ajax post to another domain? - outlook-addin

I'm developing an Outlook Add-in with external editor (vs-code) and with browsersync.
When I try to post via ajax i got the following error:
Failed to load
https://my_domain/report/v1/?id=YWFhfDIzfDMyNHwxfDl8MTE: Response to
preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'https://my_local:8443' is therefore not allowed
access. The response had HTTP status code 404.
I've tried to change cors to true in bsconfig.json.
My ajax function:
function ajax_post_request (url) {
var data = []
var request = $.ajax({
url: url,
async: true,
type: 'POST',
})
return request
}
How to enable Cors and Access-Control-Allow-Origin' correctly?

My final working ajax function:
function ajax_post_request (url, body) {
var request = $.ajax({
data: body,
crossDomain: true,
cache: false,
url: url,
async: true,
type: 'POST',
})
return request
}
My NGINX web proxy to allow CORS:
...
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control';
...

Related

My request has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header

``I am new with API requests, I have to use an API with authentication but I have an error. I have tried to solve the cors but I have not found the solution. When I put mode no-cors I have error 401. The API is external, I haven't access to modify anything
fetch("https://xxxxxxx",{
method:"GET",
headers: {
'Content-type' : 'application/json',
'Access-Control-Allow-Origin': '*',
"X-AMC-Vendor-Key": "xxxxxxxxx"
}
})
.then(res => res.json())
.then(
(result) => {
console.log('rsult 1', result)
},
(error) => {
// handle error
console.log('error', error)
}
)
Server also needs to allow cors, or add allow cors to response object.
Access-Control-Allow-Origin : //set this field as the client domain or *
Access-Control-Allow-Origin : http://example.client.come // this will give example.client.com as a client to bypass cors by browser
or
Access-Control-Allow-Origin: * // this will allow any client server to access the api on server domain

Response to preflight request doesn't pass access control No 'Access-Control-Allow-Origin'

I have a Vue.js application that uses axios to send request to ApiGee Server.
This is the code i use to send request to APIgee.
const headers = {
'X-API-Key': 'randomKey123123'
}
return axios({
method: 'get',
url: url,
headers: headers
}).then(response => {
console.log(response)
})
from the ApiGee, I can see OPTIONS request being received first since I done the request from the client side browser.
I can also see the X-API-Key header key but the value is missing.
The error I'm getting from the browser console is
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource
Below code helped me you can try this format:
created() {
// POST request using axios with set headers
const article = { title: "Vue POST Request Example" };
const headers = {
'X-API-Key': 'randomKey123123'
};
axios.post(url, article, { headers })
.then(response => console.log(response.data)
);
}

Express Node.js Cors preflight issue 400 net::ERR_FAILED

I have been banging my head against the wall for hours now... tried every type of combination to get this working.
I have my own API endpoint here: https://app.automate.mn/api/tools/email/add
Which I am trying to post data to from 3rd party websites.
app.js
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors());
app.options('*', cors());
...
const {addContact} = require('./routes/api/tools/email');
app.post('/api/tools/email/add', addContact);
addContact.js
addContact: async function (req, res) {
res.status(200).send('OK - TEST');
return;
}
I have setup a test website here with the form: https://demoautomatemn.wpcomstaging.com/
When you submit the form, it's posting the data to the endpoint:
loadForm.js
automate_post_data('https://app.automate.mn/api/tools/email/add', data)
.then(data => {
console.log(data); // JSON data parsed by `data.json()` call
});
async function automate_post_data(url = '', data = {}) {
const response = await fetch(url, {
method: 'POST',
mode: 'cors', // no-cors, *cors, same-origin
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
//referrerPolicy: 'origin', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
body: JSON.stringify(data) // body data type must match "Content-Type" header
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status} - ${response.statusText}`);
}
return response.json();
}
The post is failing:
Access to fetch at 'https://app.automate.mn/api/tools/email/add' from origin 'https://demoautomatemn.wpcomstaging.com' 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.
loadForm.js:109 POST https://app.automate.mn/api/tools/email/add net::ERR_FAILED
I was expecting to see the "Access-Control-Allow-Origin" in the response headers for the OPTION call but nothing (Preflight response is not successful). I have tried everything to get it working.
Any suggestions would be so welcome right now.
OK, Progress but no cigar!
I setup the following:
Setting at apache level:
https://docs.bitnami.com/bch/infrastructure/nodejs/administration/enable-cors-nodejs/
You might also find this helpful: https://enable-cors.org/server_apache.html
Adding origin to the request
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Origin': window.location.href
},
referrerPolicy: 'origin',
This then resulted in the error message changing:
Access to fetch at 'https://app.automate.mn/api/tools/email/add' from origin 'https://demoautomatemn.wpcomstaging.com' has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.
Update 'Content-Type': 'application/x-www-form-urlencoded',
As per this post: Why doesn't adding CORS headers to an OPTIONS route allow browsers to access my API?
I updated the request to x-www-form-urlencoded
const response = await fetch(url, {
method: method,
mode: 'cors', // no-cors, *cors, same-origin
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Origin': window.location.href
},
referrerPolicy: 'origin', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
body: data // body data type must match "Content-Type" header
});
It feels like progress however I am still getting 406 error:
POST https://app.automate.mn/api/tools/email/add 406
Response {type: "cors", url: "https://app.automate.mn/api/tools/email/add", redirected: false, status: 406, ok: false, …}

Aurelia HttpClient.Fetch to get token from Auth0 but works fine in Postman

I have no trouble getting a bearer token returned when using Postman. However, when using Aurelia, I receive a status 200 with "OK" as the only response. I see that the Request Method is still "OPTIONS". I see this in the Chrome Console:
Failed to load https://------.auth0.com/oauth/token: Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers in preflight response.
But, from what I can see the headers shown in the response and from what I'm seeing everything looks like it's there.
Here's what I receive from Postman:
Response: Status 200 OK
JSON:
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGci...{shortened for brevity}",
"expires_in": 86400,
"token_type": "Bearer"
}
Here's code from Aurelia:
private getToken() {
var postData = { "client_id": API_CONFIG.clientId, "client_secret": API_CONFIG.clientSecret, "audience": API_CONFIG.audience, "grant_type": "client_credentials" };
this.http.fetch('https://kimberlite.auth0.com/oauth/token', {
credentials: 'omit',
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': 'http://localhost:3000/'
},
mode: 'cors',
method: 'post',
body: JSON.stringify(postData)
}).then(result => result.json())
.then(data => {
localStorage.setItem('api_access_token', data.access_token);
localStorage.setItem('api_expires_at', new Date().getTime() + data.expires_in);
});
}
I've searched and haven't found anything that's helped me get passed this. What am I missing? Any help greatly appreciated
After reading Jesse's comment below, I removed the header for the 'Access-Control-Allow-Origin' and receive the same 200 OK. However, receive error in Google Chrome Origin 'localhost:3000'; is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.".
After reading other questions, I attempted removing all headers and I receive a 401 Unathorized with the following response {{"error":"access_denied","error_description":"Unauthorized"}
private getToken() {
var postData = { "client_id": API_CONFIG.clientId, "client_secret": API_CONFIG.clientSecret, "audience": API_CONFIG.audience, "grant_type": "client_credentials" };
let http = new HttpClient();
http.fetch('https://kimberlite.auth0.com/oauth/token', {
credentials: 'omit',
//headers: {
// 'Content-Type': 'application/json'
//},
mode: 'cors',
method: 'post',
body: JSON.stringify(postData)
}).then(result => result.json())
.then(data => {
localStorage.setItem('api_access_token', data.access_token);
localStorage.setItem('api_expires_at', new Date().getTime() + data.expires_in);
});
}
ok, I just tried in Firefox, using only the 'Content-Type' header and received expected response. Is there something with Chrome (which most users are going to be using) that I need to be aware of?
You shouldn't set the access-control-allow-origin header on the request. In a CORS request, the server endpoint needs to set this header on the response of your OPTIONS request.
The way that Cross-Origin Resource Sharing works, is that the client first makes an OPTIONS call to the server endpoint. The server endpoint should be configured to use CORS, and have a list of origins that are allowed (or simply a * to allow all origins). Then on the response to this OPTIONS request, the server will set the Access-Control-Allow-Origin: https://localhost:3000 to indicate the origin is allowed to make the request. You can see this in your response too:
The client then proceeds to make the GET or POST call to the same endpoint and actually retrieve/store the data.
In your case, if you make the request using the Aurelia fetch client, you don't need to set a header to do this. You can simply do the following:
private getToken() {
var postData = { "client_id": API_CONFIG.clientId, "client_secret": API_CONFIG.clientSecret, "audience": API_CONFIG.audience, "grant_type": "client_credentials" };
this.http.fetch('https://kimberlite.auth0.com/oauth/token', {
credentials: 'omit',
headers: {
'Content-Type': 'application/json'
},
mode: 'cors',
method: 'post',
body: JSON.stringify(postData)
}).then(result => result.json())
.then(data => {
localStorage.setItem('api_access_token', data.access_token);
localStorage.setItem('api_expires_at', new Date().getTime() + data.expires_in);
});
}

Trouble getting an Authentication Token using Axios for React

I'm trying to grab an authentication token using axios in a react app.
Here is the error I'm getting is:
"XMLHttpRequest cannot load https://api.mmitnetwork.com/Token. Response for preflight has invalid HTTP status code 400"
Here is my code.
var App = React.createClass({
getInitialState() {
return {
token: ''
}
},
componentDidMount() {
var _this = this;
axios.post('https://api.mmitnetwork.com/Token', {
grant_type: 'password',
username: 'jpdesigning',
password: 'Upahem2_88'
}).then((response) => {
console.log('Success!')
_this.setState({
token: response.data
})
}).catch((error) => {
console.log(error)
})
},
render() {
return (
<div className="App">
{this.state.token}
</div>
);
}
})
export default App;
Your server needs to allow cross-origin (CORS) clients to access your headers by setting the following header on your server's response and telling it which headers they are (here you are allowing two headers: Authorization & Permissions - i.e. including custom headers)
Access-Control-Expose-Headers: Authorization, Permissions
Headers that are accessible by default:
Cache-Control
Content-Language
Content-Type
Expires
Last-Modified
Pragma
Read here Access-Control-Expose-Headers
example from php server for full CORS access
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Credentials: true ");
header("Access-Control-Allow-Methods: OPTIONS, GET, POST");
header("Access-Control-Expose-Headers: Authorization");
header("Access-Control-Allow-Headers: Content-Type, Depth, User-Agent, X-File-Size,
X-Requested-With, If-Modified-Since, X-File-Name, Cache-Control");
you need to set withCredentials: true, header , this will send the cookie along with this request