The following code works fine using internet explorer and receives a 200 response. However, using Firefox generates a 405. When using fiddler I can see that IE passes the json object but firefox doesn't.
app.service('UserService', function ($http) {
this.GetLoginStatus = function (AuthenticateRequest) {
$http.defaults.useXDomain = true;
$http({
url: APIURL + '/Authenticate',
method: "POST",
options: {},
data: AuthenticateRequest,
headers: {'Content-Type': 'application/json'}
}).success(function (data, status, headers, config) {
console.log(data);
console.log(status);
console.log(headers);
console.log(config);
}).error(function (data, status, headers, config) {
console.log(data);
console.log(status);
console.log(headers);
console.log(config);
});
};
});
Fiddler inspection
FireFox
OPTIONS http://www.myapi.com:56586/V1/Service.svc/json/Authenticate HTTP/1.1
Host: localhost:56586
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: http://www.myapi.com:54567
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type,x-requested-with
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
IE
POST http://www.myapi.com:56586/V1/Service.svc/json/Authenticate HTTP/1.1
X-Requested-With: XMLHttpRequest
Accept: application/json, text/plain, /
Content-Type: application/json
Referer: http://www.myapi.com:54567/
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; Touch; rv:11.0) like Gecko
Host: localhost:56586
Content-Length: 45
DNT: 1
Connection: Keep-Alive
Pragma: no-cache
{"UserName":"username","Password":"password"}
Related
I am trying to query an API that should return a json object of books that match a user's query.
The problem is what I am getting in the code is a promise rather than teh json object.
In the Chrome dev tools I can see I am getting a 200 response from the server with a Type of json and the object there is what I am expecting to receive.
When I console.log the result of the query it comes up as a promise though.
Pretty new to this but my understanding is that I should be getting a json object when searchBook is set with a query string in my SearchBooks component
SearchBooks.js
import React, { Component } from 'react'
import * as BooksAPI from './utils/BooksAPI'
// import Book from './Book';
export default class SearchBooks extends Component {
state = {
query: ''
}
updateQuery = (query) => {
this.setState(() => ({
query: query
}))
}
clearQuery = () => {
this.updateQuery('')
}
searchBook = (query) => {
return BooksAPI.search(query)
}
searchFromQuery = () => {
return this.state.query.split(' ').map((b) => (
this.searchBook(b)
))
}
render() {
const { query } = this.state
// const { onUpdateShelf } = this.props
const showingBooks = query === ''
? 'No results'
: this.searchFromQuery()
return(
<div className="search-books">
<div className="search-books-bar">
<a className="close-search" >Close</a>
<div className="search-books-input-wrapper">
<input
type="text"
placeholder="Search by title, author or subject"
value={query}
onChange={(event) => this.updateQuery(event.target.value)}
/>
</div>
</div>
<div className="search-books-results">
<ol className="books-grid">
{/* <Book
key={book.id}
book={book}
updateShelf={onUpdateShelf} /> */}
</ol>
</div>
</div>
)
}
}
API Request Function
export const search = (query) =>
fetch(`${api}/search`, {
method: 'POST',
headers: {
...headers,
'Content-Type': 'application/json'
},
body: JSON.stringify({ query })
}).then(res => res.json())
.then(data => data.books)
Result of console.log(this.searchFromQuery())
[Promise]
0
:
Promise
__proto__
:
Promise
[[PromiseStatus]]
:
"resolved"
[[PromiseValue]]
:
Array(20)
length
:
1
__proto__
:
Array(0)
Request/Response Headers
// Request
POST /search HTTP/1.1
Host: reactnd-books-api.xxxxx
Connection: keep-alive
Content-Length: 13
Accept: application/json
Origin: http://localhost:3000
Authorization: 2nhixsfp
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36
Content-Type: application/json
Referer: http://localhost:3000/search
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
// Response
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Content-Type: application/json; charset=utf-8
ETag: W/"78c1-CfIO/Nda/QZYUxfCqeekUjLL3SU"
Date: Wed, 23 May 2018 15:15:00 GMT
Transfer-Encoding: chunked
Content-Encoding: gzip
X-Berlioz-Country: GB
Access-Control-Allow-Headers: X-Berlioz-Country
Access-Control-Expose-Headers: X-Berlioz-Country
Strict-Transport-Security: max-age=300;
Request URL: https://xxxx.com/search
Request Method: POST
Status Code: 200 OK
Remote Address: xxxxx
Referrer Policy: no-referrer-when-downgrade
Access-Control-Allow-Headers: X-Berlioz-Country
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: X-Berlioz-Country
Content-Encoding: gzip
Content-Type: application/json; charset=utf-8
Date: Wed, 23 May 2018 15:15:00 GMT
ETag: W/"78c1-CfIO/Nda/QZYUxfCqeekUjLL3SU"
Strict-Transport-Security: max-age=300;
Transfer-Encoding: chunked
X-Berlioz-Country: GB
X-Powered-By: Express
Accept: application/json
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
Authorization: 2nhixsfp
Connection: keep-alive
Content-Length: 13
Content-Type: application/json
Host: reactnd-books-api.udacity.com
Origin: http://localhost:3000
Referer: http://localhost:3000/search
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36
{query: "p"}
query
:
"p"
Calling res.json() on a response from fetch returns a promise that resolves to the body of the request in JSON format. What you should do is setting some state with the data coming from the request. You can do it this way:
export default class SearchBooks extends Component {
state = {
query: '',
books: []
}
updateQuery = (query) => {
this.setState(() => ({
query: query
}))
}
clearQuery = () => {
this.updateQuery('')
}
searchBook = (query) => {
// Instead of returning the promise, you add the response data to the state
BooksAPI.search(query)
.then(books => this.setState(prevState => ({ books: prevState.books.concat(books)})));
}
render() {
const { query } = this.state
// const { onUpdateShelf } = this.props
const showingBooks = query === ''
? 'No results'
: this.searchBook(query)
return(
<div className="search-books">
<div className="search-books-bar">
<a className="close-search" >Close</a>
<div className="search-books-input-wrapper">
<input
type="text"
placeholder="Search by title, author or subject"
value={query}
onChange={(event) => this.updateQuery(event.target.value)}
/>
</div>
</div>
<div className="search-books-results">
<ol className="books-grid">
{this.state.books.map(book => <Book key{book.id} book={book} updateShelf={onUpdateShelf} />)}
</ol>
</div>
</div>
)
}
}
This is the general idea, just take the value from the promise and set it to the state. You can expand on this as needed.
When I make a request in Chrome to the webserver on my localhost, the headers are:
HTTP/1.1 200 OK
Server: nginx/1.9.12
Date: Sat, 03 Sep 2016 18:44:54 GMT
Content-Type: application/json
Content-Length: 520
Connection: keep-alive
Set-Cookie: session="\350C\243\0153RB`\225M4vyD\317\030"; HttpOnly
Strict-Transport-Security: max-age=31536000
When I make a subsequent request to the server, the headers are:
GET /api/larps HTTP/1.1
Host: 192.168.99.100
Connection: keep-alive
accept: application/json
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36
content-type: application/json
Referer: https://192.168.99.100/simple.html
Accept-Encoding: gzip, deflate, sdch, br
Accept-Language: en-US,en;q=0.8
Here is a webpage demonstrating the issue:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Test</title>
</head>
<body>
<script>
const fetch_get_json = url => _fetch(url, 'GET');
const fetch_post_json = (url, data) => _fetch(url, 'POST', data);
const _fetch = (url, method, data) => {
console.log('fetching', url)
const params = {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
method
}
if (data) {
params.body = JSON.stringify(data);
};
return fetch(url, params);
}
fetch_post_json('/api/login', {email: 'user', 'pwd': 'password'}).then(function() {
fetch_get_json('/api/info');
});
</script>
</body>
</html>
Why isn't the cookie being sent?
I am very new to angularjs.
I am trying to make the http call and posting object to the api which only accept json.
'use strict';
// Declare app level module which depends on views, and components
var app = angular.module('ngShow', ['ngRoute','ngResource']);
app.
config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/login', {templateUrl: 'partials/login.html' });
$routeProvider.otherwise({redirectTo: '/login'});
}]);
app.
config(['$httpProvider', function($httpProvider) {
delete $httpProvider.defaults.headers.common['X-Requested-With'];
$httpProvider.defaults.headers.common['Access-Control-Max-Age'] = '1728000';
$httpProvider.defaults.headers.common['Accept'] = 'application/json, text/javascript';
$httpProvider.defaults.headers.common['Content-Type'] = 'application/json; charset=utf-8';
$httpProvider.defaults.useXDomain = true;
}]);
but seems doesn't work from the request headers.
Request Headers 15:31:10.000
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0
Pragma: no-cache
Origin: http://localhost:63342
Host: localhost:8080
DNT: 1
Connection: keep-alive
Cache-Control: no-cache
Access-Control-Request-Method: POST
Access-Control-Request-Headers: access-control-max-age
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
UPDATE #001
Added my loginService.js - it is calling the api ok but just not the json.
app.factory('loginService', function($http){
return{
login:function(user){
console.log("enter login service");
var $promise=$http.post('http://localhost:8080/api/login',user); //send data to the api
$promise.then(function(msg){
if(msg.data=='succes') console.log('succes login');
else console.log('error login');
});
}
}
});
I've got following concerns here:
You use 2 config sections for one module. Not sure if this approach is expected.
Accordingly the documentation, such params are set in run section
Assuming that the user param in the login() method of your loginService factory is the object you want to send as your JSON payload, you can try the following:
var payload = JSON.stringify(user);
var promise = $http({
url: '/api/login',
method: 'POST',
data: payload,
headers: {'Content-Type': 'application/json'}
});
promise.then(function(...) {
...
});
UPDATE:
I would also consolidate the two .config() calls in your code.
app.config(['$routeProvider', '$httpProvider', function($routeProvider, $httpProvider) {
$routeProvider.when('/login', {templateUrl: 'partials/login.html' });
$routeProvider.otherwise({redirectTo: '/login'});
delete $httpProvider.defaults.headers.common['X-Requested-With'];
$httpProvider.defaults.headers.common['Access-Control-Max-Age'] = '1728000';
$httpProvider.defaults.headers.common['Accept'] = 'application/json, text/javascript';
$httpProvider.defaults.headers.common['Content-Type'] = 'application/json; charset=utf-8';
$httpProvider.defaults.useXDomain = true;
}]);
You're already setting the Content-Type header globally (i.e. for all requests) using $httpProvider.defaults.headers.common['Content-Type'], so the headers: {'Content-Type': 'application/json'} in my code above is redundant.
In order to send a file as part of my form, I changed the content type to "multipart/form-data", but when I check the console, it's still using application/json;charset=utf-8 And Node.js (with Sails.js framework) prints an error saying it's invalid JSON.
Here is the code:
$rootScope.objects.user.withHttpConfig({
transformRequest: angular.identity
}).customPUT($scope.objects.user, "", { // user object contains a file
'Content-Type': "multipart/form-data" // should change content-type. I've tried using `undefined` as well
}).then(function(resp) {
if (resp == "OK") {
$scope.successes = [{
msg: "Saved"
}];
}
}, function(err) {
console.log(err);
$scope.errors = err.data.errors;
});
The "Inspect Network Request" tab in Google Chrome reads:
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:30.0) Gecko/20100101 Firefox/30.0
Referer: http://localhost:1337/user/settings
Host: localhost:1337
DNT: 1
Content-Type: application/json;charset=utf-8
Content-Length: 505679
Connection: keep-alive
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Accept: application/json, text/plain, */*
As said in comment above and According to docs you should pass headers as fourth parameter. So your code should be
$rootScope.objects.user.withHttpConfig({
transformRequest: angular.identity
}).customPUT(
$scope.objects.user,
undefined,
undefined,
{
'Content-Type': "multipart/form-data"
}
).then(function(resp) {
if (resp == "OK") {
$scope.successes = [{
msg: "Saved"
}];
}
}, function(err) {
console.log(err);
$scope.errors = err.data.errors;
});
Reference url : https://github.com/mgonto/restangular#custom-methods
I am trying to connect to a table score that exits in a flash game.
When using the browser the header that i am sending it's this one
POST /game/json?h=c1234567890f HTTP/1.1
Host: pt3.forgeofempires.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:20.0) Gecko/20100101 Firefox/20.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cookie: sid=awsndax7nsow; req_page_info=game_v1; start_page_type=game; start_page_version=v1
Connection: keep-alive
Referer: http://cdn.pt.forgeofempires.com/swf/Main.swf?123456789
Content-type: application/x-www-form-urlencoded
Content-length: 161
34c4ceb6d8[{"requestClass":"ClanService","requestMethod":"getOwnClanData","requestData":[],"requestId":1,"__class__":"ServerRequest","clientVersionNumber":0.31}]
After looking for a while (my acknowledgement in JavaScript is not that height), i did find some examples and after understanding them i did make my own code.
function test(){
var header =
{
'Host': 'pt3.forgeofempires.com',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; rv:20.0) Gecko/20100101 Firefox/20.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en-US,en;q=0.5',
'Accept-Encoding': 'gzip, deflate',
'Cookie': 'sid=awsndax7nsow; req_page_info=game_v1; start_page_type=game; start_page_version=v1',
'Connection': 'keep-alive',
'Referer': 'http://cdn.pt.forgeofempires.com/swf/Main.swf?123456789',
'Content-type': 'application/x-www-form-urlencoded',
'Content-length': '161',
'': '96c4ceb6d9[{"requestClass":"ClanService","requestMethod":"getOwnClanData","requestData":[],"requestId":4,"__class__":"ServerRequest","clientVersionNumber":0.31}]'
}
var url = "http://pt3.forgeofempires.com/game/json?h=c1234567890f";
var h = {
'method' : "post",
'payload' : header
};
var response = UrlFetchApp.fetch(url, h);
return response;
}
When i run the code it goes always to the login page.
Not sure if this is happening because of any script error or simple because it's a different ip address accessing to my account.
No sure as well how to send the last part, because the last part it's a text data only.
Any help will be appreciated... thanks in advance
You are adding your headers as a payload. UrlFetchApp provides a way to add headers. Use that
var h = {
'method' : "post",
'headers' : header
};
var response = UrlFetchApp.fetch(url, h);
I'm not sure what your payload is. In the list of headers, there is a blank header - is this the payload ? If yes, then you have to add the payload separately.
var h = {
'method' : "post",
'headers' : header,
'payload' : '96c4ceb6d9[{"requestClass":"ClanService","requestMethod":"getOwnClanData","requestData":[],"requestId":4,"__class__":"ServerRequest","clientVersionNumber":0.31}]'
};
var response = UrlFetchApp.fetch(url, h);
Note: Ensure that you remove the blank header from the list of headers.