Why is GM_xmlhttpRequest ignoring its data parameter? - post

According to its documentation, GM_xmlhttpRequest should be able to take a data parameter as part of its argument.
However, I can't seem to get it to work.
I have a simple server that echoes the parameters given to it:
require 'sinatra'
require 'json'
get '/' do
JSON.dump params
end
post '/' do
JSON.dump params
end
And a simple greasemonkey script that just tries to POST some data to the server.
It tries to pass data as query parameters in the URL and as postdata:
// ==UserScript==
// #name PostDataTest
// #namespace Test
// #description Simple test of GM_xmlhttpRequest's data parameter
// #include http://localhost:4567/
// #version 1
// #require http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
// #grant metadata
// #grant GM_xmlhttpRequest
// ==/UserScript==
var url = '/?q0=0&q1=1';
var data = 'd0=0&d1=1'
GM_xmlhttpRequest({ method: 'POST', url: url, data: data, onload: function(r){
console.log('gm:' + r.responseText);
}});
$.post(url, data, function(d,s,r){
console.log('jq:' + r.responseText);
});
When I POST postdata using jQuery, it works fine, but any postdata I POST using GM_xmlhttpRequest is ignored:
jq:{"q0":"0","q1":"1","d0":"0","d1":"1"}
gm:{"q0":"0","q1":"1"}
This leads me to believe that GM_xmlhttpRequest isn't actually using the data parameter I'm giving it. (I'm not sure b/c I can't monitor GM_xmlhttpRequest's network activity in Firebug).
What's going on here? Did I screw something up? Did the API shift? How can I use GM_xmlhttpRequest to post data without packing it into the URL?

Ok, I used the TamperData firefox add-on to monitor my GM_xmlhttpRequests (which were sending the postdata) to see what they were doing differently.
The difference was four headers. Where jQuery sent
Accept: */*
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: http://localhost:4567/
GM_xmlhttpRequest sent:
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Content-Type: text/plain; charset=UTF-8
Using the headers: parameter I was able to specify the Content-Type of my GM_xmlhttpRequest, which got it to work.
// ==UserScript==
// #name PostDataTest
// #namespace Test
// #description Simple test of GM_xmlhttpRequest's data parameter
// #include http://localhost:4567/
// #version 1
// #require http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
// #grant metadata
// #grant GM_xmlhttpRequest
// ==/UserScript==
var url = '/?q0=0&q1=1';
var data = 'd0=0&d1=1'
GM_xmlhttpRequest({
method: 'POST',
url: url+'gm',
data: data+'gm',
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
onload: function(r){
console.log('gm:' + r.responseText);
}});
$.post(url+'jq', data+'jq', function(d,s,r){
console.log('jq:' + r.responseText);
});

Related

http-header doesn't get set on iOS

An ruby (Sinatra) API sends a header __authorization__ to the front end application (vuejs) that uses axios.
This works fine on desktops. On a URL called /getJWT the response headers contain:
__authorization__: eyJhI1NiJ9.eyJ1c2VyIjoijE2NzYxMzA0NjB9.4bSrsh-E2pX2pXeC89Bec
access-control-expose-headers : __authorization__
(__authorization__ contains a valid jwt).
on iOS, the header doesn't get set. On the same URL, I get :
__authorization__:
access-control-expose-headers : __authorization__
(__authorization__ is empty).
On the API-side, I have :
get '/getjwt' do
# HTTP_COOKIE contains the refresh token and rack session token
# remove useless part of HTTP_COOKIE to get value of refresh token
refresh = request.env['HTTP_COOKIE']
.sub(/__refresh_token__=/, '') # remove key __refresh_token__
.sub(/;[^;]*$/,'') # remove the first semicolon and everything after the semicolon
settings.jwt = getjwt(refresh)
headers '__authorization__' => settings.jwt
json_status 204
end
and in the Vuejs app, I put the jwt that the __authorization__ header is supposed to send in a pinia store like so:
function getJWT() {
const jwt = getData.get('/user/b/getjwt')
jwt
.then((response) => {
setJWT(response.headers['__authorization__'])
})
.catch((err) => { alert(err) })
return jwt
}
function setJWT(jowt) {
jwt.value = jowt
}
In this code, getDatais an Axios configuration:
const getData = axios.create({
baseURL: import.meta.env.VITE_API_ROOT,
withCredentials: true,
method: 'get',
headers: {
'Content-Type': 'application/json',
},
})

dart http give me 400 before send out request and response's body is blank string

I am making POST request using http lib in Dart. After I wandering around former answers with no luck. Even official doc
import 'package:http/http.dart' as http;
Future<http.Response> createAlbum(String nameEN) {
return http.post(
'http://localhost:8000/api/products/',
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(<String, String>{
'nameEN': nameEN,
}),
);
}
And I test with unittest like this
testWidgets('POST request from offcial docs', (WidgetTester tester) async{
final http.Response res = await createAlbum("Jordan");
print(res.statusCode);
});
Attempt:
PostmanApp can make request and get 201 in response. However, when I copy&paste the Dart code from it and test it does not work
I always get 400 and no request comes to localhost:8000
testWidgets('POST request from postman', (WidgetTester tester) async{
var headers = {
'Content-Type': 'application/json'
};
var request = http.Request('POST', Uri.parse('localhost:8000/api/products/'));
request.body = '''{\n "name_jp": "李天宝",\n "name_en": "Sarit",\n "description": "Developer",\n "qty": 3,\n "expiry": "2099-12-25",\n "barcode": "549XXXYYYYYY",\n "price": "{\\"bounds\\": \\"[)\\", \\"lower\\": \\"12\\", \\"upper\\": \\"6\\"}",\n "medium_price": 60\n}''';
request.headers.addAll(headers);
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {
print(200);
print(await response.stream.bytesToString());
}
else {
print(response.statusCode);
print(response.reasonPhrase);
}
});
Problem
Dart response returned to me is 400 and on the server side request has not been sent out to my http://localhost:8000/api/products/
Question:
What is the correct POST syntax?
References:
HTTP POST with Json on Body - Flutter/Dart
Bad state: Cannot set the body fields of a Request with content-type "application/json"
Flutter FormatException: Unexpected character (at character 1)
Http POST request with json content-type in dart:io
You have non-ASCII characters. Did you set the proper ; charset=UTF-8 in your Content-Type header? Or even better, JSON doesn't understand non-ASCII unless you \u encode them.
Lesson learnt here
Add CORS enable in chrome
flutter run -d web. Do not use -d chrome
Make request from cors enabled chrome by clicking. Do not use unittest!

How to post parameters from angular to rails server

I am fairly new to angular and i am trying to send a name and image file to my server which is written in rails. But the data i am being received on my server is not correct and i have tried many fixes but nothing seems to be working. The request payload that being sent is this
-----WebKitFormBoundaryhRvQy5dRArcb6BfP
Content-Disposition: form-data; name="project[logo]"; filename="badge.png"
Content-Type: image/png
------WebKitFormBoundaryhRvQy5dRArcb6BfP
Content-Disposition: form-data; name="project[name]"
abc
------WebKitFormBoundaryhRvQy5dRArcb6BfP--
This is not being accepted in rails server and returns me a bunch of gibberish in the console/log
��2˾F
2ƺx���;p}}�0���'�C�F
��b7�Ӡ�}��c��Ii���W8��I#�<dy���}4�|���{c��5�iV�#�����*�����'��
:ظ׻�<+�I5��^��ԓk�qi���R91R��pi7QZϢ�����V�m��� �(��8�m�c%OGN#�k��k2�>_O�����^Ya��+�����1������^�����K�3�07q���{7�ܶ0+��&sZ�򽽴���w7�>f�^��A�/����d�����g�i�
PG?_��u�����5�i2��F$��\7(�ԟ�t8e9�3�9=Lk�#��ֽ��3��%FJ�QjI����f���qmI4֍4�^��P|�S���)Ԋ0Җ�AEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPE�����͊O6c��>y?횜����5�Z��Nuf��qr}ݶK�N�K�k̨BU'E^Ri/�W���G/�C�W?f��
RT������ׯ!�8a\�z�_^���Z�ݺEm�(��|��GJ�iS�8�k�{��ۻ��#��+"(��(�`��+��(��(��(��$��"��
2:�V��G��j���K`�S�LI���s�C�����+�����-h)[��q�
��/�^洫T��NMw[�^�z?]���%��ki
z�ͭ��f+��T��a���� S��H:��dz���{2���5
���A#���qڇ��t�D�D2LGz�q��`��nM|�/)�B�z���K��^p__�
���
This is my service.ts
postCreateProject(logo, name)
{
const formData: FormData = new FormData();
const url = EndPoints.BASE_URL + EndPoints.Projects;
formData.append('project[logo]', logo);
formData.append('project[name]', name)
console.log(formData.get('project[logo]'))
return this.httpService.postFileUpload(url, formData);
This is my postFileUpload in the httpService
postFileUpload(url: string, fmd: FormData): Observable<any> {
console.log('post file upload')
const headers = new HttpHeaders();
headers.append('Form-Data','FileUpload');
// headers.set('Content-Type', 'multipart/form-data');
// headers.set('Accept', 'application/json');
return this.http.post(url, fmd, {headers : headers});
}
If you need additional files please ask. Thanks for helping.
If you're using rails 5+ and angular 4+, you might try excluding the headers and just having
return this.http.post(url, fmd).
That's what I do (rails 6 with angular 10) and the data on the rails end is correct.

Missing access token for authorization on Ebay Browse API

I try to search items from eBay API. Within the server.js file at my Apollo Server 2, I pass the token string by context property while instantiation (s. Doku: Apollo context argument). So every request contains the authentication HTTP header property. As a tryout, for now, I just use the fixed token string. This will be changed later if I work for the client.
server.js
import { ApolloServer } from 'apollo-server'
import schema from './schema'
const server = new ApolloServer({
schema,
context: ({ req }) => {
const token = 'Bearer v^1.1#i^1#I^3#f^0#p^1#r^0#t^H4sIAAA...' // my token
return {
...req,
headers: {
...req.headers,
// enrich the header with oauth token
authorization: token,
},
}
},
})
server.listen().then(({ url }) => console.log(`🚀 Server ready at ${url}`))
resolver method
// A map of functions which return data for the schema.
const resolvers = {
Query: {
books(root, { keyword = '' }, context) {
console.log(context.headers)
fetch(`https://api.ebay.com/buy/browse/v1/item_summary/?q=${keyword}`)
.then(response => response.json())
.then(json => console.log(json))
return []
}
}
}
The context.header contains the authorization property:
{ host: 'localhost:4000',
connection: 'keep-alive',
'content-length': '108',
accept: '*/*',
origin: 'http://localhost:4000',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
dnt: '1',
'content-type': 'application/json',
referer: 'http://localhost:4000/',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'de,en;q=0.9',
authorization: 'Bearer v^1.1#i^1#f^0#p^1#r^0#I^3#t^H4sIAAAAAAAAAOV...'
}
The JSON response contains the error with errorId 1002. It says Access token is missing in the Authorization HTTP request header.:
{ errors:
[ { errorId: 1002,
domain: 'OAuth',
category: 'REQUEST',
message: 'Missing access token',
longMessage: 'Access token is missing in the Authorization HTTP request header.' } ] }
Additionally, I use a new browser tab, enter the URL https://api.ebay.com/buy/browse/v1/item_summary/search?q=test and add the same authorization header property (I use the ModHeader chrome extension). I hit enter, the request works and I get the expected JSON.
It is confusing and I don't know what I'm doing wrong while passing the token. Does somebody have an idea?
The headers you see are the ones being sent in the request to your GraphQL server. All you've done is modified them to include the Authorization header and then included your entire request object as your context -- you're not passing any header information to the fetch call actually getting the data from eBay. Minimally, you want to do something like this:
fetch(`https://api.ebay.com/buy/browse/v1/item_summary/?q=${keyword}`, {
headers: {
Authorization: context.headers.authorization,
},
})
Also bear in mind that the fetch call should be returned inside your resolver, otherwise it won't be awaited.

Delete entry from database with WinJS and OData

I'm trying to delete an entry from the database by odata. I get the error message
{"error":{"code":"","message":{"lang":"en-US","value":"Bad Request - Error in query syntax."}}}
my code:
function deleteMonthEntry() {
var item = actMonthEntries.getItem(listIndex);
var queryString = "Stundens(" + item.data.datensatz_id + ")?$format=json";
var requestUrl = serviceUrl + queryString;
WinJS.xhr({
type: "delete",
url: requestUrl,
headers: {
"Content-type": "application/json"
}
}).done(
function complete(response) {
},
function (error) {
console.log(error);
}
);
}
My request URL looks like this:
requestUrl = "http://localhost:51893/TimeSheetWebservice.svc/Stundens(305233)?$format=json"
Thanks
Marlowe
At least I found the solution:
I've entered an filter request to my service like this:
TimeSheetWebservice.svc/Stundens?$filter=datensatz_id eq 305221
this returned the correct entry with this link:
TimeSheetWebservice.svc/Stundens(305221M)
So if I enter a M after the ID, everything works fin. But I have no idea where this M comes from.
Can anyone tell me the reason for this M? It does not belong to the ID. The ID is this
305221
Marlowe
Are you sure the server you're talking to supports the $format query option? Many don't. I would try removing that part of the request URI, and instead modify your headers value to specify an Accept header:
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
}
For servers where $format is allowed, giving it a json value is equivalent to providing an Accept header with the application/json MIME type.
In general, for a DELETE operation, the Accept header or $format value only matters for error cases. With a successful DELETE, the response payload body will be empty, so there's no need for the server to know about your format preference.

Resources